In a Bash terminal on Linux, this works fine:
# define some bash func
foo() {
echo "foo"
}
# Back up your system's default PS1 prompt 1 string, which controls the prompt
# output
if [ -z "$PS1_BAK" ]; then
PS1_BAK="$PS1"
fi
# Set the PS1 prompt 1 string to run the `foo` function every time the
# prompt is printed
PS1='$(foo)'"\n$PS1_BAK"
Now, every time I press Enter, it prints foo
above my command prompt, as expected. Example:
foo
gabriel@my_computer:~$
foo
gabriel@my_computer:~$
foo
gabriel@my_computer:~$
I want the same behavior on Windows in the Git Bash terminal which comes with Git for Windows. This trick is how I make my terminal automatically tell me the git branch, hash, and tag whenever I am inside a git repo. (See where I set my PS1
string via PS1=
here).
However, in Git Bash on Windows, the above code produces this error instead:
bash: command substitution: line 1: syntax error near unexpected token `)'
bash: command substitution: line 1: `foo)'
Why? And more importantly: how do I make it work in Git Bash on Windows?
Note that the Git Bash terminal is based on MSYS2, if that helps.
Update:
Replace the definition of foo
above with:
foo() {
echo "$(pwd)"
}
...to print the present working directory, and you get the same behavior still: Linux works, Git Bash does not. Git Bash has problems with command substitution in the prompt strings.
The already-existing PS1
prompt string uses backtick-style command substitution, so that is what we have to use. Here is the default PS1
variable provided in Git Bash on Windows, as shown by echo "$PS1"
:
'\[\033]0;$TITLEPREFIX:$PWD\007\]\n\[\033[32m\]\u@\h \[\033[35m\]$MSYSTEM \[\033[33m\]\w\[\033[36m\]`__git_ps1`\[\033[0m\]\n$'
Notice this part: `__git_ps1`
. The __git_ps1
part is a Bash function they provide, so wrapping it in backticks makes it do command substitution.
So, the solution for use in Git Bash on Windows is to use backtick-style command substitution instead. For my case, it would look like this:
PS1='`foo`'"\n$PS1_BAK"
Now it works fine in both Linux and in Git Bash on Windows.
@thatotherguy also pointed out to me in this comment that there's an existing bug report about this in MSYS2.
See here: MSYS2: bash: '\n' after command substitution in $PS1 causes error #1839.
Trial and error tells me that only the older style ``
instead of $()
works in the PS1
prompt string in Git bash.
I also left a comment about this here: Backticks vs braces in Bash:
In Git Bash they are not always equivalent. Inside the
PS1
prompt string, active command substitution must use backticks!:`command`
vs$(command)
. See my answer here: Cannot use command substitution inside Git Bash on Windows: "bash: command substitution: line 1: syntax error near unexpected token `)'"
Though this answer is entirely written by me, I did have a chat with an AI to prompt me to try the `command`
command substitution style instead of the $(command)
style.
I prompted GitHub Copilot with this:
difference in command substitution with
$()
vs backticks.
And it gave me some information which prompted me to try backtick-style command substitution instead.
I cannot say whether or not `command`
is generally more portable, but clearly it works in Git Bash on Windows where $(command)
does not.