Расширение тильды в зш

11

Я наткнулся на это поведение Zsh при использовании FreeBSD:

% dd if=/dev/zero bs=1M count=1 of=~/test2
dd: failed to open '~/test2': No such file or directory

Это действительно смутило меня, потому что то же самое прекрасно работает в bash.

Я могу touchфайлы, используя тильду в Zsh, а затем lsих:

% touch ~/test2
% ls ~/test2
/home/christoph/test2

Сначала я предположил, что zsh не понимает, что после этого идет путь, of=поэтому он не расширяется ~. Но автозаполнение имен файлов работает просто отлично. Фактически, если вы используете существующее имя файла, начинаете его путь с ~, а затем нажимаете Tab в какой-то момент, путь расширяется в набираемой мной команде.

Почему zsh переходит ~/test2на ddнет /home/christoph/test2?

Zsh ведет себя так же в Linux. Фактически, я выполнил эти команды выше и скопировал их результаты на машине Linux.

UTF-8,
источник
Вы можете использовать $HOMEвместо ~.
Иларио Джелметти

Ответы:

15

~расширяется только в нескольких контекстах . POSIX, для стандартных shмандатов echo a=~для вывода a=~(в то время как он требует ~расширения в a=~одиночку).

zshоднако есть magicequalsubstопция, которую вы можете использовать для ~расширения после, =даже если это не в назначениях или аргументах псевдоключевых слов export/ typeset....

Так:

$ echo a=~
a=~
$ set -o magicequalsubst
$ echo a=~
a=/home/chazelas

Обратите внимание , что 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=~
Стефан Шазелас
источник