在旧 Solaris 机器上的 ksh 中,我使用了:
export PS1="$PWD $"
将提示符设置为当前目录。它工作得很好,直到你在其他地方 cd ,然后你会发现它并不是每次都评估 PWD 。我注意到它是通过像这样设置 PS1 来修复的:
export PS1="\$PWD $"
只是好奇它叫什么,它是如何工作的,其他应用程序等等。(这是那些很难用谷歌搜索的东西之一。)
答案1
一些文档将有助于解释这一点。
以下变量将影响 shell 的执行:
PS1:每次交互式 shell 准备好读取命令时,该变量的值将进行参数扩展并写入标准错误。
...
单引号
将字符括在单引号中应保留单引号内每个字符的字面值。
...
双引号
用双引号括起来的字符应保留双引号内所有字符的字面值,$ 除外
:美元符号应保留其引入参数扩展的特殊含义
...
转义字符(反斜杠)
未加引号的反斜杠应保留后续字符的字面值。
因此 的值PS1
受参数扩展的影响,这就是您想要的,因此$PWD
每次收到提示时都会对其进行评估。这意味着$PWD
的值中需要有一个实际的字符串PS1
。但,
PS1="$PWD $ "
将把值PWD
运行赋值语句时进入PS1
。PS1
会是这样的/home/poldie $
,之后就永远不会改变。你不想要这样。
PS1="\$PWD $ "
反斜杠将引用$
,以便PS1
包含文字字符串$PWD $
。你要这个。
PS1='$PWD $ '
也会做同样的事情。当参数被单引号括起来时,参数不会被扩展。
(注意:我最初将所有这些作为export
语句,因为 OP 选择将它们写为export
语句。@Kusalananda 删除了它们。我不确定为什么。如果您想要子 shell(例如由:sh
vi 中的命令)以保留您的自定义提示符。)
答案2
该\
字符对后面的(特殊)字符进行转义。在这种情况下,它转义了$
我们通常用来取消引用变量的 。当 shell 计算变量赋值时,它首先扩展表达式的右侧。如果没有\
before $PWD
,shell 会扩展$PWD
并将结果分配给PS1
.
但是,对于\
,shell 将其$PWD
视为文字字符串,并将其按原样分配给PS1
,以便PS1
包含字符串$PWD
,而不是变量 的扩展值$PWD
。当shell即将显示提示符时,它再次进行变量扩展,而这一次,因为$PS1
contains $PWD
,没有\
,shell 成功将其扩展到当前目录。
可以使用相同的方法在 shell 脚本中创建动态变量名称(NetBSDrcNG
系统非常广泛地使用此方法,特别是在控制网络接口的脚本中,其中 NetBSD 和 FreeBSD 中的网络适配器指定数量使得为每个适配器显式编码变得不切实际)。