PS1='$(pwd)' 为什么这有效以及为什么这与 PS1=$(pwd) 不同

PS1='$(pwd)' 为什么这有效以及为什么这与 PS1=$(pwd) 不同

为什么当我输入此命令时,提示符会更改为我的目录?

PS1='$(pwd)'

我使用单引号,这意味着没有插值,又名echo '$(pwd)'——→$(pwd)

此外,假设我们澄清了为什么它有效……为什么它的功能与 不同PS1=$(pwd)? (根本没有引号)

不同的是,我的意思是,如果我使用引号,那么当我在终端中导航时,提示将不断更改为我的当前目录。但是如果我不使用引号,那么提示将始终保留我第一次输入命令时所在的目录PS1=$(pwd)

为什么?

答案1

当您简单地将值分配给变量时,$(...)除非将表达式括在单引号(或反斜杠转义)中,否则将计算该表达式。要理解,请尝试比较这两者:

A=$(pwd)
echo "$A"
B='$(pwd)'
echo "$B"

的值A立即变成字符串/home/yourusername,显然它不记得这个字符串来自哪里,即使您更改目录它也保持不变。然而,的值B将成为文字字符串,$(pwd)而不会被解释。

现在,PS1发生了一些特殊的事情:每当打印提示时,都会解释某些特殊的结构,例如,命令替换的执行方式$(...)与上面对变量赋值时发生的方式完全相同A。显然,如果您PS1包含主目录的文字字符串(如上面的A),那么它就无法更改。但是,如果它包含字符串$(pwd)(如上面的B),那么每当打印提示时都会对其进行评估,从而显示您的实际目录。

答案2

在 bash 和 zsh 中, 的值PS1并不按原样用作提示符,它进行了一些扩展。两个 shell 的规则有所不同,但在这两种情况下,步骤之一是使用与普通 shell 语法相同的语法(、、或、、)执行“美元”扩展(变量替换、命令替换、算术求值) 。$VARIABLE${VARIABLE}$(COMMAND)`COMMAND`$((EXPRESSION))$[EXPRESSION]

  • 在 bash 中,美元扩展默认打开,但可以通过以下命令关闭shopt -u promptvars
  • 在 zsh 中,美元扩展默认处于关闭状态,但很多人(以及您在网络上找到的大多数配置框架)将其打开setopt prompt_subst

当提示符中的美元扩展打开时,PS1='$(pwd)'设置PS1为 6 个字符的值$(pwd),从而导致$(pwd)被替换,从而pwd每次 shell 显示新提示符时执行命令。另一方面,PS1=$(pwd)设置PS1为当时 shell 的当前工作目录。如果您关闭了美元扩展,那么PS1='$(pwd)'将导致提示成为文字字符串$(pwd)

请注意,有更方便的方法可以在提示符中获取工作目录:

  • 在 bash 中,用反斜杠转义例如\w,它将您的主目录缩写为 ,~并且可以通过设置进行修剪PROMPT_DIRTRIM
  • 在 zsh 中,使用逃逸率例如%/或者%~%/与 相同$PWD%~缩写主目录),可以进行修剪设置。
  • 在任一 shell(以及任何其他 Bourne 风格的 shell)中,$PWD相当于$(pwd):您不需要运行子进程来获取当前工作目录。

答案3

因为如果没有引号,$(pwd) 将在设置 PS1 时进行评估。使用引号,$(pwd) 的计算将被推迟,直到显示提示。

如果没有引号,PS1 将在设置 PS1 时设置为当前目录。使用单引号 PS1 设置为 $(pwd),这意味着每次显示提示时它将评估并打印当前目录。

相关内容