Adam Rackis
Adam Rackis

Reputation: 83358

Why does function call from PS1 require escaping?

I'm setting my prompt inside of .bash_profile like this

export PS1="\w\$(getBranchName)\n ---->"

My getBranchName function exists, and this works, fine.

My question is, why do I need to escape the call to getBranchName like this \$(getBranchName).

In other words, why doesn't this code work, instead?

export PS1="\w$(getBranchName)\n ---->"

If curious, this is what the getBranchName function looks like

esc="\033"
redf="${esc}[31m"
green="${esc}[32m"
purple="${esc}[35m"
cyanf="${esc}[36m"
reset="${esc}[0m"

getBranchName() {
  if [[ "$(__git_ps1 '%s')" == "master" ]]
  then
    echo -e "${redf}$(__git_ps1)${reset}";
  else
    echo -e "${cyanf}$(__git_ps1)${reset}";
  fi
}

export PS1="\w\$(getBranchName)\n ---->"

Upvotes: 4

Views: 271

Answers (3)

Aserre
Aserre

Reputation: 5062

You need to escape the dollar because you want to store this exact text in your variable.

Try it by typing echo "$PS1". You should see the exact text : \w$(getBranchName)\n ---->

If you didn't escape it, the function would be evaluated only once, during the allocation.


The bottom line is that PS1 is a special variable : every time you display a new line in the console, the variable is evaluated to extract the display settings.

Upvotes: 7

Toby Speight
Toby Speight

Reputation: 30718

It's escaped because you want it to run when the shell evaluates $PS1 each time it's displayed, not just during the assignment.

The other expansions (which should be using tput unless you actually like random control codes all over your non-ANSI terminals) you want to be expanded just once, when you assign to PS1.

Upvotes: 2

Holger Just
Holger Just

Reputation: 55718

The PS1 variable is basically a template string (which might contain function calls) which is evaluated each time the prompt is shown.

If you want to evaluate a function each time, so that each prompt shows the result of this new execution, you need to escape the call.

If you would embed the function call directly in the string, the function would be called once immediately (i.e. likely during login) and your PS1 will contain the result of this single function call as evaluated during your initial login. Thus, the value won't be updated again since the function is not called anymore (since the PS1 doesn't contain the function call anymore but only the static result of one).

Upvotes: 3

Related Questions