我在尝试运行 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
。