Differences between revisions 7 and 8
Revision 7 as of 2010-03-23 21:00:17
Size: 2676
Editor: GreyCat
Comment: retain the previous answer (with the sgr0 correction) as an alternative
Revision 8 as of 2010-03-23 21:39:37
Size: 3281
Editor: cE67647C1
Comment: comment response
Deletions are marked like this. Additions are marked like this.
Line 37: Line 37:
  ''Fair enough. I initially just intended to change the BLACK= to a RESET= (since not everyone uses white on black), but then I thought it would be better if the prompt did not depend on variables being available. I obviously was not aware about the possibility of such terminal escape sequences, so I think mentioning the single-quote version first would be a better idea and also mention what happens if those vars change.
   
  I guess one could also make the variables readonly to prevent accidentally changing them and mess up the prompt, though that'll probably have other drawbacks..?'' -- ~~~

I have a fancy prompt with colors, and now bash doesn't seem to know how wide my terminal is. Lines wrap around incorrectly.

You must put \[ and \] around any non-printing escape sequences in your prompt. Thus:

fancy_prompt() {
  local blue=$(tput setaf 4)
  local purple=$(tput setaf 5)
  local reset=$(tput sgr0)
  PS1="\[$blue\]\h:\[$purple\]\w\[$reset\]\\$ "
}

Without the \[ \], bash will think the bytes which constitute the escape sequences for the color codes will actually take up space on the screen, so bash won't be able to know where the cursor actually is.

If you still have problems, e.g. when going through your command history with the Up/Down arrows, make sure you have the checkwinsize option set:

shopt -s checkwinsize

Refer to the Wikipedia article for ANSI escape codes.

  • Personal note: I still prefer this answer:

    BLUE=$(tput setaf 4)
    PURPLE=$(tput setaf 5)
    RESET=$(tput sgr0)
    PS1='\[$BLUE\]\h:\[$PURPLE\]\w\[$RESET\]\$ '

    I understand that people like to avoid polluting the variable namespace; hence the function and the local part, which in turn forces the use of double quotes, which in turn forces the need to double up some but not all backslashes (and to know which ones -- oy!). I find that unnecessarily complicated. Granted, there's a tiny risk of collision if someone overrides BLUE or whatever, but on the other hand, the double-quote solution also carries the risk that a terminal will have backslashes in its escape sequences. And since the contents of the escape sequences are being parsed in the double-quote solution, but not in the single-quote solution, such a terminal could mess things up. Example of the difference:

     imadev:~$ FOO='\w'; PS1='$FOO\$ '
     \w$ FOO='\w'; PS1="$FOO\\$ "
     ~$ 

    Suppose our terminal uses \w in an escape sequence. A \w inside a variable that's referenced in a single-quoted PS1 is only expanded out to a literal \w when the prompt is printed, which is what we want. But in the double-quoted version, the \w is placed directly into the PS1 variable, and gets evaluated by bash when the prompt is printed. Now, I don't actually know of any terminals that use this notation -- it's entirely a theoretical objection. But then again, so is the objection to the use of variables like BLUE. And some people might actually want to echo "$BLUE" in their shells anyway. So, I'm not going to say the single-quote answer is better, but I'd like to see it retained here as an alternative. -- GreyCat

    • Fair enough. I initially just intended to change the BLACK= to a RESET= (since not everyone uses white on black), but then I thought it would be better if the prompt did not depend on variables being available. I obviously was not aware about the possibility of such terminal escape sequences, so I think mentioning the single-quote version first would be a better idea and also mention what happens if those vars change.

      I guess one could also make the variables readonly to prevent accidentally changing them and mess up the prompt, though that'll probably have other drawbacks..? -- ~~~

BashFAQ/053 (last edited 2022-09-14 02:03:48 by emanuele6)