zsh에서 물결표 확장

zsh에서 물결표 확장

FreeBSD를 사용하는 동안 zsh의 이러한 동작을 우연히 발견했습니다.

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

Bash에서도 똑같은 일이 잘 작동하기 때문에 이것은 나를 정말 혼란스럽게 합니다.

touchzsh에서 물결표를 사용하여 파일을 만들 수 있습니다 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할 수 있는 옵션이 있습니다 .~=exporttypeset

그래서:

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

bashPOSIX/ 모드가 아닌 경우 shin은 왼쪽 내용이 따옴표가 없는 리터럴 변수 이름처럼 보이는 경우에만 확장됩니다 ~(/ 또는 다른 명령에 대한 인수에 있는지 여부에 관계 없음) .word=~=bashtypesetdeclareexport

$ 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=$HOMEecho "a=$HOME"


리터럴 및 인용되지 않은 콘텐츠 또는 globsubst활성화된 확장 프로그램에 의해 생성된 콘텐츠만 해당됩니다.파일 이름 확장자(별도.....와일드카드또한 ~으로 알려진파일 이름 생성)은 (시뮬레이션에서와 같이) 활성화되지 않을 때마다 실행되는 ~형태입니다 . 이 두 가지 출력을 찾을 수 있습니다 .shfileexpansionshvar='a=~' zsh -o magicequalsubst -o globsubst -c 'echo $var'var='a=~' zsh -o magicequalsubst -c 'echo $~var'a=/home/dir

² 물결표 확장 자체는 이전 버전의 bash에서 globbing을 거치지 않는 한 분할+glob을 거치지 않습니다. 그럼에도 불구하고 물결표 확장은 큰따옴표 안에서 수행되지 않습니다.

관련 정보