3

I can change my cursor shape like this:

printf "\x1b[\x31 q" # block :)
printf "\x1b[\x35 q" # ibeam :)

But when I assign that to a variable with %s and expand using printf, it doesn't work:

CURSOR="\x1b[\x3%s q"

printf ${CURSOR} 1 # block :(
printf ${CURSOR} 5 # ibeam :(

How do I fix this?

6
  • 1
    Possible duplicate of Why does my shell script choke on whitespace or other special characters? or any of the questions linked to Security implications of forgetting to quote a variable in bash/POSIX shells. In short, quote your variables!. Commented Apr 19, 2019 at 19:45
  • @StéphaneChazelas, Where am I missing double quotes here?! It would have been awesome if this is fixed with a double quotes; Or do you mean quote in some general sense?
    – Nishant
    Commented Apr 19, 2019 at 19:49
  • 1
    Please read those Q&As Commented Apr 19, 2019 at 19:53
  • 1
    In the second set of commands, the arguments printf sees are \x1b[\x3%s, q and 1 (or 5). Since printf reuses format strings until the arguments are exhausted, the format string is printed twice, once with q replacing %s and once with 1 (or 5). You should quote your variables there; otherwise it has a completely different meaning.
    – muru
    Commented Apr 19, 2019 at 20:20
  • 1
    Do you know that printf does not support hex backslash escapes? Your code is not portable as it relies on non-POSIX features.
    – schily
    Commented Apr 23, 2019 at 16:06

2 Answers 2

4

\x31 is the character 1 and \x35 is 5, so in this case you don't have to use escape sequences.

CURSOR="\x1b[%s q"

printf "${CURSOR}" 1
printf "${CURSOR}" 5
1
  • I thought I knew a little bit of escaping, now I understand that it is an ocean :-).
    – Nishant
    Commented Apr 20, 2019 at 9:43
3

By using \x3%s, only \x3 is interpreted as an escape sequence, the %s is no longer part of it. If you want to make that part an argument, you'll have to use %b and bring out the whole \x31 to have that interpreted as an escape sequence:

$ printf "\x1b[\x31 q" | od -c
0000000 033   [   1       q
0000005
$ printf "\x1b[%b q" "\x31" | od -c
0000000 033   [   1       q
0000005
1
  • Thanks for showing how to use debugging tools likeod. I was struggling to print these characters on the screen :-)
    – Nishant
    Commented Apr 20, 2019 at 9:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .