![为什么波形符 (~) 与以破折号开头的 CLI 参数一起使用时不会扩展?](https://linux22.com/image/147426/%E4%B8%BA%E4%BB%80%E4%B9%88%E6%B3%A2%E5%BD%A2%E7%AC%A6%20(~)%20%E4%B8%8E%E4%BB%A5%E7%A0%B4%E6%8A%98%E5%8F%B7%E5%BC%80%E5%A4%B4%E7%9A%84%20CLI%20%E5%8F%82%E6%95%B0%E4%B8%80%E8%B5%B7%E4%BD%BF%E7%94%A8%E6%97%B6%E4%B8%8D%E4%BC%9A%E6%89%A9%E5%B1%95%EF%BC%9F.png)
我在尝试运行 VNC 服务器 (x0vncserver) 时损失了几个小时,并且客户端拒绝连接并显示奇怪的消息
No password configured for VNC Auth
服务器也打印这个错误
SVncAuth: opening password file '~/.vnc/passwd' failed
好吧,我浪费了很多时间,直到我意识到波浪号既不是由 shell 扩展的,也不是由 x0vncserver 扩展的。然后我运行了这些测试
$ echo --PasswordFile=~/.vnc/passwd
--PasswordFile=~/.vnc/passwd
但
$ echo PasswordFile=~/.vnc/passwd
PasswordFile=/home/tichomir/.vnc/passwd
这是为什么?如果参数以破折号开头,为什么 shell 拒绝展开波浪号?我认为波浪线只要不被引用就会总是扩展,但显然还有另一个规则在起作用?
答案1
bash
这是shell 手册中描述的一个特性:
当单词作为简单命令的参数出现时,Bash 还会对满足变量赋值条件的单词(如上面的参数中所述)执行波浪号扩展。在 posix 模式下,除了上面列出的声明命令之外,Bash 不会执行此操作。
这意味着bash
将要展开字符串中的波形符PasswordFile=~/.vnc/passwd
,因为它是echo
一个看起来像变量赋值的参数。
该字符串--PasswordFile=~/.vnc/passwd
看起来不像变量赋值,因为该字符串--PasswordFile
不是有效的变量名称。
请注意,bash
在 POSIX 模式下运行时不会执行此操作,并且默认情况下其他 shell(例如zsh
、ksh
或yash
)不会执行此操作(不过,zsh
有一个magicequalsubst
选项可以在不带引号的等号 ( ) 之后执行波浪号扩展=
)。
如果要确保当前用户的主目录路径作为命令参数的一部分正确扩展,请使用该$HOME
值而不是波浪号:
echo --PasswordFile="$HOME/.vnc/passwd"
手册中提到的“上面列出的声明命令”是内置命令alias
、declare
、typeset
、export
、readonly
、 和local
。