FreeBSD를 사용하는 동안 zsh의 이러한 동작을 우연히 발견했습니다.
% 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 시스템에 복사했습니다.
답변1
~
일부 경우에만 연장. POSIX, 표준 sh
요구사항 echo a=~
출력용 (별도의 확장이 a=~
필요함 )~
a=~
zsh
하지만 / ... 유사 키워드 의 할당이나 매개변수에 없더라도 ¹ 이후에 확장 magicequalsubst
할 수 있는 옵션이 있습니다 .~
=
export
typeset
그래서:
$ echo a=~
a=~
$ set -o magicequalsubst
$ echo a=~
a=/home/chazelas
bash
POSIX/ 모드가 아닌 경우 sh
in은 왼쪽 내용이 따옴표가 없는 리터럴 변수 이름처럼 보이는 경우에만 확장됩니다 ~
(/ 또는 다른 명령에 대한 인수에 있는지 여부에 관계 없음) .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=~
$HOME
어떤 경우에도 ( zsh 및 분할+glob²을 방지하기 위해 인용된 인수 확장이 필요한 다른 Bourne 유사 쉘에서)를 ~
항상 사용할 수 있습니다 .echo a=$HOME
echo "a=$HOME"
리터럴 및 인용되지 않은 콘텐츠 또는 globsubst
활성화된 확장 프로그램에 의해 생성된 콘텐츠만 해당됩니다.파일 이름 확장자(별도.....와일드카드또한 ~으로 알려진파일 이름 생성)은 (시뮬레이션에서와 같이) 활성화되지 않을 때마다 실행되는 ~
형태입니다 . 이 두 가지 출력을 찾을 수 있습니다 .shfileexpansion
sh
var='a=~' zsh -o magicequalsubst -o globsubst -c 'echo $var'
var='a=~' zsh -o magicequalsubst -c 'echo $~var'
a=/home/dir
² 물결표 확장 자체는 이전 버전의 bash에서 globbing을 거치지 않는 한 분할+glob을 거치지 않습니다. 그럼에도 불구하고 물결표 확장은 큰따옴표 안에서 수행되지 않습니다.