Shell – echo literal question mark in PS1

promptshell

I'm new to shell scripting and trying to make myself a nice prompt to show me the state of my git branch, using colors and characters like "?".

when I have new untracked files, I want my PS1 to be like:

p/a/t/h/ (staging ?) $

i.e. pwd (branchName space questionMark) $

I've simplified my problem to this code (~/.bashrc):

parseGitBranch () {
     gitBranch=staging
     ifUntrackedFiles="$gitBranch ?"
     echo $ifUntrackedFiles
 }

 PS1="`parseGitBranch` $ "

My problem is that because of the space before the question mark, PS1 treats it as a wildcard and shows me any single letter file exists in my directory.

p/a/t/h/ (staging ?) touch a
p/a/t/h/ (staging ?) source ~/.bashrc
p/a/t/h/ (staging a) $

Without the space it works well but I still want the space after my branch name :\

p/a/t/h/ (staging?) $

I've also tried:

ifUntrackedFiles="$gitBranch"' ?'

echo -e

and a backslash before the mark outputs them both (staging \?)

How to escape the question mark in PS1?

Thanks!

Best Answer

In Bourne shell, not quoting a variable (i.e. $var instead of "$var") should be the exception. The problem here is your echo command. With echo ?, ? is substituted with every one-letter file in your directory, whereas with echo "?", the question mark is displayed as is.

Your function should then be:

parseGitBranch () {
     gitBranch=staging
     ifUntrackedFiles="$gitBranch ?"
     echo "$ifUntrackedFiles"
 }

And, since back-quotes are easy to confuse with single quotes and difficult to nest, use $(...) instead:

 PS1='$(parseGitBranch) $ '
Related Question