3

The default .bashrc file for Debian-based systems sets $PS1 like this:

PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

What confuses me is that ${debian_chroot} part. According to StackOverflow: Difference between single and double quotes in bash, if single-quotes are used when defining a string, characters such as $ should be treated as a literal, rather than evaluate variables.

Doesn't this mean that Bash should actually print out ${debian_chroot:..., and not the value of that variable? Or are there more syntax rules involved here?

Community
  • 1
  • 1
IQAndreas
  • 8,060
  • 8
  • 39
  • 74

2 Answers2

5

You'd normally be right, except the value of PS1 is expanded again at runtime as part of generating the prompt. This is specifically to allow expansions at runtime.

PS1='$PWD: ' will expand $PWD when the prompt is shown, so that you always see the current directory.

PS1="$PWD: " will expand $PWD when the prompt is defined, so that you always see the directory you were in when you defined the prompt.

that other guy
  • 116,971
  • 11
  • 170
  • 194
  • This is a bit of a side question, but how is the value of `PS1` "expanded again" when the prompt is shown? What lines of code would achieve this? – IQAndreas May 31 '14 at 22:23
  • 1
    It's actually an entirely separate expansion mode ([source code](https://gitorious.org/bash/bash/source/81287b9114c72f606e3b9d52215da4ffef729045:y.tab.c#L7360)) that handles both backslash expansions and `$` type expansions (subject to the `promptvars` shell option). There's no good way of replicating the same functionality through bash code. – that other guy May 31 '14 at 23:22
0

It's often simpler to use PROMPT_COMMAND to set the value of PS1 each time it is used. This way, you don't have to escape code in PS1 itself.

make_prompt () {
    PS1="${debian_chroot:+($debian_chroot)}\u@\h:\w\$ "
}

PROMPT_COMMAND='make_prompt'
chepner
  • 497,756
  • 71
  • 530
  • 681