Bash 引用嵌套和大括号
Bash quote nesting and curly braces
根据 Change gnome-terminal title to reflect the current directory? 我尝试使用:
PROMPT_COMMAND='echo -ne "3]0;$(basename ${PWD})[=11=]7"'
...在我的~/.bashrc
标题栏中gnome-terminal
表示当前目录的名称。
大部分情况下它工作正常;但是如果我尝试从以下目录打开 gnome-terminal
:
/run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C008%5D/Internal shared storage/DCIM/Camera
...然后它失败了:
basename: extra operand ‘storage/DCIM/Camera’
Try 'basename --help' for more information.
...每次提示即将显示在终端中。
显然问题出在目录名中的空格(即使 ${PWD}
中的花括号原则上应该避免引号)。所以,我尝试用引号转义,结果证明这不是微不足道的(显然只是单引号转义 \"${PWD}\"
不起作用) - 我能得到的最好的是:
PROMPT_COMMAND='echo -ne "3]0;$(basename \\"${PWD}\\")[=14=]7"'
... 可以正常工作 - 但它会在 gnome-terminal 标题中打印一个额外的反斜杠;例如,在这种情况下,标题是:Camera\
.
PROMPT_COMMAND
的正确构造是什么,以便它正确处理带空格的目录,并且只打印没有附加反斜杠的目录(例如 Camera
)?
为什么要转义双引号?
PROMPT_COMMAND='echo -ne "3]0;$(basename "${PWD}")[=10=]7"'
是正确的。我们可以遍历嵌套级别:
顶层单引号。在单引号内,您不需要转义双引号。您需要通过 '\''
“转义”单引号(实际上,这是字符串连接,但这与此处无关)。
二层双引号。在双引号内,如果您尝试编写文字 "
,则需要 \"
。然而,你还有第三层:
$()
/ 命令替换。该层在执行时不会在其周围看到双引号(单引号将是另一回事 - 您需要 '\''
)。 Bash 将正确解析类似 echo "$(echo "my variable is $foo")"
.
的内容
此外,${PWD}
中的花括号与引号无关。 ${PWD}
和$PWD
从任何角度看都没有区别。只有当您的变量与其他“单词”字符对接时,花括号才会起作用:
echo PWD_$PWD_USER_$USER // expands variables "USER" and "PWD_USER_"
echo PWD_${PWD}_USER_$USER // expands variables "USER" and "PWD"
根据 Change gnome-terminal title to reflect the current directory? 我尝试使用:
PROMPT_COMMAND='echo -ne "3]0;$(basename ${PWD})[=11=]7"'
...在我的~/.bashrc
标题栏中gnome-terminal
表示当前目录的名称。
大部分情况下它工作正常;但是如果我尝试从以下目录打开 gnome-terminal
:
/run/user/1000/gvfs/mtp:host=%5Busb%3A001%2C008%5D/Internal shared storage/DCIM/Camera
...然后它失败了:
basename: extra operand ‘storage/DCIM/Camera’
Try 'basename --help' for more information.
...每次提示即将显示在终端中。
显然问题出在目录名中的空格(即使 ${PWD}
中的花括号原则上应该避免引号)。所以,我尝试用引号转义,结果证明这不是微不足道的(显然只是单引号转义 \"${PWD}\"
不起作用) - 我能得到的最好的是:
PROMPT_COMMAND='echo -ne "3]0;$(basename \\"${PWD}\\")[=14=]7"'
... 可以正常工作 - 但它会在 gnome-terminal 标题中打印一个额外的反斜杠;例如,在这种情况下,标题是:Camera\
.
PROMPT_COMMAND
的正确构造是什么,以便它正确处理带空格的目录,并且只打印没有附加反斜杠的目录(例如 Camera
)?
为什么要转义双引号?
PROMPT_COMMAND='echo -ne "3]0;$(basename "${PWD}")[=10=]7"'
是正确的。我们可以遍历嵌套级别:
顶层单引号。在单引号内,您不需要转义双引号。您需要通过
'\''
“转义”单引号(实际上,这是字符串连接,但这与此处无关)。二层双引号。在双引号内,如果您尝试编写文字
"
,则需要\"
。然而,你还有第三层:
的内容$()
/ 命令替换。该层在执行时不会在其周围看到双引号(单引号将是另一回事 - 您需要'\''
)。 Bash 将正确解析类似echo "$(echo "my variable is $foo")"
.
此外,${PWD}
中的花括号与引号无关。 ${PWD}
和$PWD
从任何角度看都没有区别。只有当您的变量与其他“单词”字符对接时,花括号才会起作用:
echo PWD_$PWD_USER_$USER // expands variables "USER" and "PWD_USER_"
echo PWD_${PWD}_USER_$USER // expands variables "USER" and "PWD"