zsh 中波浪号的扩展

UTF*_*F-8 11 zsh tilde

我在使用 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 传递~/test2dd,而不是/home/christoph/test2

zsh 在 Linux 上的行为相同。事实上,我执行了上面的这些命令,并在 Linux 机器上复制了它们的输出。

Sté*_*las 16

~仅在少数情况下扩展。POSIX,用于输出的标准sh指令(而它需要单独扩展)。echo a=~a=~~a=~

zsh但是,即使它不在/ ... 伪关键字的赋值或参数中magicequalsubst,您也可以使用该选项~进行扩展。=exporttypeset

所以:

$ 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)