다음 코드는 내가 시도한 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 ... then
Zsh는 특정 상황에서 같은 줄에 세미콜론 없이만 허용한다는 사실이 혼란스럽습니다 . 조건부 직위 배정은 특별한 경우인 것 같습니다. 문서에는 언제 세미콜론이 필요한지 정확히 나와 있지 않습니다.
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
rc
Bourne과 유사한 쉘이나 -like 쉘 fish
에서 유효합니다 . 그리고 , in 및 in을 사용 /path/to/grep
하여 실행하는 것을 의미합니다(셸은 시스템에서 호출하는 모든 인터페이스 앞에 위치합니다 ).grep
foo
file
argv[]
LC_ALL=C
envp[]
execve(file, argv[], envp[])
then
따라서 파서가 이 토큰을 / 구성의 키워드로 받아들이고 인식하는 것은 전혀 놀라운 일이 아닙니다. then
이는 명령이 필요한 모든 곳에서 필요하기 때문입니다.if
fi
then
또한 다음을 수행할 수 있음을 알 수 있습니다.
if then else (echo foo) fi
같은 이유로.
그러나 문서화되지 않았으며 향후 변경될 수 있으므로 이에 의존하지 않을 것입니다.
if true then
or 에는 if echo then
분명히 /에 대한 인수가 있지만 then
구조에는 해당 인수가 없습니다.true
echo
if
then
실제로 POSIX에서는 then
(구문상) 키워드로 인식되는 것을 허용하지 않습니다.var='value'
sh
POSIX 요구 사항:
var=value keyword
keyword
키워드로 인식되지는 않지만 실행될 명령의 이름으로 그다지 유용하지는 않습니다. 하지만 POSIX 쉘 키워드 다음에 명령 이름을 지정하는 사람은 아무도 없습니다.
예를 들어 POSIX에는 다음이 필요합니다.
var=value if true
if
true
인수로 전달되고 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"
바라고 있습니다.\if
if
var=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
구성을 취했습니다. 그런 다음 이러한 구조가 중복되므로 삭제하십시오.