Замена команды PS1 не выполняется при содержании новых строк на msys bash


Эта команда выполняется успешно

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

Однако, если я добавляю новую строку, это не удается

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

Если я использую backticks, это работает

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

Но отступать не рекомендуется. Так в чем же причина этой ошибки?

GNU bash, version 4.2.45(6)-release
2 13

2 ответа:

Вы можете легко устранить неоднозначность синтаксического анализа, чтобы предотвратить попадание любого такого бага (хотя я не могу воспроизвести его сам):

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

Этот синтаксис $'\n' разбирает до литерального символа новой строки, тогда как '\n' разбирает до строки, содержащей двухсимвольную \n escape-последовательность.

Для получения дополнительной информации о том, как $'' отличается от '' (расширение экранированных обратным слешем последовательностей) обратитесь кBash Hackers Wiki .

У меня была похожая проблема с .git-prompt, Когда я попытался включить его в свой PS1 на bash (MSYS2) на Windows. Проблема в том, что \n, Если я удаляю его, все работает гладко, но я хочу сломать линию.

Кстати на Linux все работает нормально.

bash выполняется так: 4.3.42(5)-release (x86_64-pc-msys)

старый, проблемный PS1:

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

исправлено:

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

упрощенная версия (без цветов, копировать-вставить-редактировать):

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

Ура Чарльз Даффи находим проблему!