PS1 command substitution fails when containing new

2020-02-09 08:08发布

This command succeeds

$ PS1='$(date +%s) $ '
1391380852 $

However if I add a newline it fails

$ PS1='$(date +%s)\n$ '
bash: command substitution: line 1: syntax error near unexpected token `)'
bash: command substitution: line 1: `date +%s)'

If I use backticks it works

$ PS1='`date +%s`\n$ '
1391381008
$

but backticks are discouraged. So what is causing this error?

GNU bash, version 4.2.45(6)-release

2条回答
唯我独甜
2楼-- · 2020-02-09 08:42

You can disambiguate the parsing easily, to prevent hitting any such bug (though I can't reproduce it myself):

PS1='$(date +%s)'$'\n$ '

This $'\n' syntax parses to a literal newline character, whereas '\n' parses to a string containing a two-character \n escape sequence.

For more info on how $'' differs from '' (expanding backslash-escaped sequences) refer to the Bash Hackers Wiki.

查看更多
手持菜刀,她持情操
3楼-- · 2020-02-09 08:50

I had a similar issue with .git-prompt when I tried to include it in my PS1 on bash (MSYS2) on Windows. The problem is the \n, if I remove it everything run smoothly but I want to break-line.

By the way on Linux everything is working fine.

The bash is run is: 4.3.42(5)-release (x86_64-pc-msys)

Old, problematic PS1:

PS1='\e[32m\]\u@\h \e[36m\]\w \e[32m\]$(__git_ps1 "(%s)")\nλ \e[0m\]$(tput sgr0)'

Fixed:

PS1='\e[32m\]\u@\h \e[36m\]\w \e[32m\]$(__git_ps1 "(%s)")'$'\nλ \e[0m\]'

Simplified version (no colors, copy-paste-edit it):

PS1='\u@\h \w $(__git_ps1 "(%s)")'$'\n$ '

Cheers Charles Duffy finding the problem!

查看更多
登录 后发表回答