我最近开始调整 bash 提示符,发现自己不明白转义字符是如何工作的。我有以下内容:
PS1="\[$RED\]\342\224\214\342\224\200"
在这里我明白了,\[
转义[
字符并\xxx
转义我的 UTF-8 字符。但在下面的行中我得到了一个奇怪的结果:
PS1+="$([·\$?·!=·0·]·&&·echo·\[$RED\]\342\234\227\·)"
这将始终X
在我的提示中打印,但如果我转义第一个,$
它只会在任何命令的退出状态不为零时打印它。我不懂为什么。不$(commands)
应该输出给定的结果commands
吗?如果我像这样转义它\$()
是整个序列转义还是只是美元符号?如果我不逃脱为什么它不打印$
?它只是打印X
.我$
对方括号内有同样的问题。为什么我必须逃避它?
我也相信这符合另一个问题,但是有没有办法在我的提示中打印实际的退出状态?
答案1
在双引号字符串中,会处理命令替换 ( $(...)
) 和变量扩展 ( $foo
),而美元符号前面的反斜杠会阻止这种情况发生,因此会删除反斜杠。这发生在作业期间PS1="$(...)"
或PS1="\$(...)"
。
但是,在打印提示时也会处理相同的扩展,因此如果在赋值时对美元符号进行转义,则结果PS1
将具有未转义的美元符号,并且在打印提示时会发生扩展。
因此,通过未转义的命令替换,该命令仅在分配提示时运行一次。使用反斜杠,它会在每次打印提示时运行。
使用这两者应该很容易测试差异:
PS1="$(date) "
PS1="\$(date) "
这\[
不同。它仅在处理提示时才相关,而不是在常规双引号字符串中。它用于标记提示中不打印任何可见字符的部分。而且,它只在提示符下起作用前扩展,所以类似的东西PS1='$(echo "\[...\]")'
可能不会做你想要的。