7

I'm trying to print bold text from the following Makefile :

printf-bold-1:
    @printf "normal text - \e[1mbold text\e[0m"

But, escape sequences are printed as-is, so when running make printf-bold-1, I got :

normal text - \e[1mbold text\e[0m

Instead of expected :

normal text - bold text

It's weird because I can print bold text from my terminal : running directly command printf "normal text - \e[1mbold text\e[0m" produces, as expected :

normal text - bold text

In the Makefile, I tried to use @echo or echo instead of @printf, or print \x1b instead of \e, but without success.

Here are some variables describing my environment (Linux with standard Gnome terminal), if that can help :

COLORTERM=gnome-terminal
TERM=xterm-256color

Note also that on some colleagues laptops (Mac), bold text is printed correctly.

What is the portable way, working on every environment, to print bold or colored text from a Makefile rule?

norbjd
  • 6,496
  • 3
  • 25
  • 56
  • 1
    I highly recommend you use single quotes here, just for safety. However, your first example worked fine for me (Ubuntu 18.04) in GNOME terminal and xterm. You absolutely cannot use `echo` for this BTW. I'm not sure exactly what you mean by using different shells: make doesn't care what shell you invoked it with. It always uses `/bin/sh` unless you set the `SHELL` variable _in your makefile_ to something different. – MadScientist Jan 04 '19 at 14:46
  • When using simple quotes, bold text is correctly printed. I can't figure why, do you have an explanation? Thanks anyway! I'll remove the part about the shells from the question as it is misleading, I don't know why I wrote that. – norbjd Jan 04 '19 at 15:06
  • 1
    It depends on if `printf` interprets \e as an escape sequence. `echo` does not without the option to tell it so: `echo -e "\e[1mbold\e[0m"` – shawnhcorey Jan 04 '19 at 15:45
  • @shawnhcorey Thanks, but I'm still not sure to understand why `printf` sometimes interpret `\e` as an escape sequence (like on my colleagues' Mac, or on @MadScientist environment) and sometimes not (my environment). – norbjd Jan 04 '19 at 16:04
  • 2
    I can't explain why you see different behavior. But I can explain why single vs. double quotes might make a difference: in single quotes the shell doesn't interpret the string at all before sending it to the program it runs (printf here). In double quotes, the shell _does_ interpret that string looking for special characters such as `$`, backquotes, etc. so it can perform operations on them. Backslash IS a special character, because it can escape things (like quotes) and the shell WILL interpret backslashes... sometimes. Depends on the shell. – MadScientist Jan 04 '19 at 17:23

2 Answers2

9

You should use the usual tput program for producing the correct escape sequences for the actual terminal, rather than hard-coding specific strings (that look ugly in an Emacs compilation buffer, for example):

printf-bold-1:
    @printf "normal text - `tput bold`bold text`tput sgr0`"

Of course, you may store the result into a Make variable, to reduce the number of subshells:

bold := $(shell tput bold)
sgr0 := $(shell tput sgr0)

printf-bold-1:
    @printf 'normal text - $(bold)bold text$(sgr0)'
Toby Speight
  • 23,550
  • 47
  • 57
  • 84
2

Ok, I got it. I should have used \033 instead of \e or \x1b :

printf-bold-1:
    @printf "normal text - \033[1mbold text\033[0m"

Or, as suggested in the comments, use simple quotes instead of double quotes :

printf-bold-1:
    @printf 'normal text - \e[1mbold text\e[0m'

make printf-bold-1 now produces :

normal text - bold text

norbjd
  • 6,496
  • 3
  • 25
  • 56