if var='value' then in Zsh: 이것이 실제로 세미콜론 없이 유효한 구문입니까?

if var='value' then in Zsh: 이것이 실제로 세미콜론 없이 유효한 구문입니까?

다음 코드는 내가 시도한 Zsh 5.8에서 작동합니다.세미콜론이 빠졌음에도 불구하고.하지만 이것이 정말 유효한 Zsh 구문일까요?

#!/bin/zsh
if var='value' then
   echo 'then'
fi

할당 결과 없음 parse error near `fi':

#!/bin/zsh
if true then
   echo 'then'
fi

세미콜론을 사용한 올바른 구문:

#!/bin/zsh
if true; then
   echo 'then'
fi

세미콜론이 없는 코드는 sh, Bash 및 Ksh 93에서 올바르지 않습니다.

if ... thenZsh는 특정 상황에서 같은 줄에 세미콜론 없이만 허용한다는 사실이 혼란스럽습니다 . 조건부 직위 배정은 특별한 경우인 것 같습니다. 문서에는 언제 세미콜론이 필요한지 정확히 나와 있지 않습니다. https://zsh.sourceforge.io/Doc/Release/Shell-Grammar.html#index-if-construct

실제로내 관심사는 Ksh입니다.. 실제로 Ksh 93을 달성하려고 하면 다음 오류가 발생합니다 syntax error at line ...: `fi' unexpected. 하지만 Zsh로 실행하면 emulate ksh잘 작동합니다. 나는 이것이 실제로 Ksh가 아니고 Zsh이고 실제 Ksh에서는 항상 실수이기 때문에 작동한다고 생각합니다.이를 확인하는 정확한 문서가 있습니까?

sh, Ksh, Bash 및 Zsh에서의 시도와 해당 출력은 다음과 같습니다. https://bitbucket.org/OPiMedia/hel언어s/src/master/comparative/shell/if_then/

답변1

할당되면 명령을 실행할 수 있습니다. 예를 들어:

LC_ALL=C grep foo file

rcBourne과 유사한 쉘이나 -like 쉘 fish에서 유효합니다 . 그리고 , in 및 in을 사용 /path/to/grep하여 실행하는 것을 의미합니다(셸은 시스템에서 호출하는 모든 인터페이스 앞에 위치합니다 ).grepfoofileargv[]LC_ALL=Cenvp[]execve(file, argv[], envp[])

then따라서 파서가 이 토큰을 / 구성의 키워드로 받아들이고 인식하는 것은 전혀 놀라운 일이 아닙니다. then이는 명령이 필요한 모든 곳에서 필요하기 때문입니다.iffithen

또한 다음을 수행할 수 있음을 알 수 있습니다.

if then else (echo foo) fi

같은 이유로.

그러나 문서화되지 않았으며 향후 변경될 수 있으므로 이에 의존하지 않을 것입니다.

if true thenor 에는 if echo then분명히 /에 대한 인수가 있지만 then구조에는 해당 인수가 없습니다.trueechoifthen

실제로 POSIX에서는 then(구문상) 키워드로 인식되는 것을 허용하지 않습니다.var='value'sh

POSIX 요구 사항:

var=value keyword

keyword키워드로 인식되지는 않지만 실행될 명령의 이름으로 그다지 유용하지는 않습니다. 하지만 POSIX 쉘 키워드 다음에 명령 이름을 지정하는 사람은 아무도 없습니다.

예를 들어 POSIX에는 다음이 필요합니다.

var=value if true

iftrue인수로 전달되고 var=value해당 환경에서 실행될 수 있는 경우 명령이 실행됩니다.

$ ln -s /bin/printenv bin/if
$ a=bar bash -c 'if a'
bash: -c: line 1: syntax error: unexpected end of file
$ bash -c 'a=foo if a'
foo
$ zsh -c 'a=foo if a'
zsh:1: parse error near `if'

zsh가 이 요구 사항을 따르지 않는 경우(시뮬레이션에서도 sh) 실제로 문제가 발생할 가능성은 거의 없습니다. 나는 누군가가 라는 명령을 호출하고 싶어하는 드문 경우에 앞에 및/또는 리디렉션이 있는지 여부에 관계없이 if명령을 작성하거나 'if'키워드 로 오인되는 것을 피하기를 "if"바라고 있습니다.\ififvar=value

$ a=bar bash -c '"if" a'
bar
$ bash -c 'a=foo "if" a'
foo
$ a=bar zsh -c '"if" a'
bar
$ zsh -c 'a=foo "if" a'
foo

참고로 POSIX에는 다음이 필요합니다.

if true; then if true; then echo x; fi fi

(둘 사이에 줄 바꿈이나 세미콜론이 없음 fi)은 이상한 요구 사항이지만 ksh88이 수행하는 작업(Bourne 셸에서 상속됨)을 지정하는 것뿐입니다. 이는 POSIX 사양이 주로 기반으로 하는 구현입니다.

zsh이 요구 사항은 존중되지 않으며 끝에 추가 단어를 추가하는 것을 허용하지 않습니다 fi.

if (true) then (echo x) fi을 포함한 대부분의 쉘에서 작동 zsh하지만 IIRC POSIX는 이 경우 해당 동작을 지정하지 않습니다.


1 실제로 역사적인 일화로 초기 Unices에는 if. 이는 Bourne 쉘이나 C 쉘 이전에 있었으며 나중에 자체 if구성을 취했습니다. 그런 다음 이러한 구조가 중복되므로 삭제하십시오.

관련 정보