我在使用 FreeBSD 时偶然发现了 zsh 的这种行为:
% dd if=/dev/zero bs=1M count=1 of=~/test2
dd: failed to open '~/test2': No such file or directory
Run Code Online (Sandbox Code Playgroud)
这真的让我很困惑,因为同样的事情在 bash 中工作得很好。
我可以touch
在 zsh 中使用波浪号文件,然后ls
它们:
% touch ~/test2
% ls ~/test2
/home/christoph/test2
Run Code Online (Sandbox Code Playgroud)
起初,我认为 zsh 没有意识到后面有一条路径,of=
所以它没有扩展~
。但是自动完成文件名工作得很好。事实上,如果使用现有文件名,以 开头~
,然后在某个时候按 Tab,路径会在我输入的命令中展开。
为什么 zsh 传递~/test2
给dd
,而不是/home/christoph/test2
?
zsh 在 Linux 上的行为相同。事实上,我执行了上面的这些命令,并在 Linux 机器上复制了它们的输出。
Sté*_*las 16
~
仅在少数情况下扩展。POSIX,用于输出的标准sh
指令(而它需要单独扩展)。echo a=~
a=~
~
a=~
zsh
但是,即使它不在/ ... 伪关键字的赋值或参数中magicequalsubst
,您也可以使用该选项~
进行扩展。=
export
typeset
所以:
$ echo a=~
a=~
$ set -o magicequalsubst
$ echo a=~
a=/home/chazelas
Run Code Online (Sandbox Code Playgroud)
需要注意的是bash
,在不POSIX /sh
模式下,扩展~
在word=~
但只有当什么左边的=
像一个未加引号的文字看起来bash
变量名(无论它是在参数typeset
/ declare
/export
或任何其它命令):
$ bash -c 'echo a=~'
a=/home/chazelas
$ bash -c 'echo "a"=~'
a=~
$ bash -c 'var=a; echo $var=~'
a=~
$ bash -c 'echo a.b=~'
a.b=~
$ (exec -a sh bash -c 'echo a=~')
a=~
Run Code Online (Sandbox Code Playgroud)