2017-09-20 2 views
2

이것은 콜론으로 구분 된 값을 루프 처리하고 각 값이 인 코드입니다.zsh는 매개 변수 확장 후 IFS로 분할하지 않습니다.

f() 
{ 
    IFS=: 
    for arg in $1 
    do 
     echo arg: $arg 
    done 
} 

f foo:bar:baz 

이것은 대부분의 POSIX 호환 쉘에서 잘 작동합니다.

$ dash foo.sh 
arg: foo 
arg: bar 
arg: baz 
$ bash foo.sh 
arg: foo 
arg: bar 
arg: baz 
$ ksh foo.sh 
arg: foo 
arg: bar 
arg: baz 
$ posh foo.sh 
arg: foo 
arg: bar 
arg: baz 
$ yash foo.sh 
arg: foo 
arg: bar 
arg: baz 

그러나 zsh에서 예상대로 작동하지 않습니다.

$ zsh foo.sh 
arg: foo:bar:baz 

zsh이 POSIX을 위반 했습니까?

+0

예, zsh을 여기에 위반 고의적으로 의도적이다. 즉, 문자열 분할에 의존하는 것은 * 모든 쉘에서 좋은 연습이 아니며 bash에서도 읽기 전용으로 -r -a args <<< "$ 1"'등을 사용하는 것이 좋습니다. $ {args [@]} "에 배열을 넣고'for arg '; do ...' –

+1

이것은'zsh'이 POSIX *가해야 할 일을하는 경우입니다. POSIX는 가능한 한 많이 기존의 동작을 유지하는 데 부담이되지 않았습니다. 최악의 해결책으로'setopt SH_WORD_SPLIT'를 사용하여 POSIX 동작을 복원 할 수 있습니다. – chepner

답변

2

예. Zsh는 자체 방식을 선택했습니다. 당신은 좀 걸릴 수

$ zsh -y foo.sh 
arg: foo 
arg: bar 
arg: baz 

: 당신이 zsh 호출에 -y 옵션을 추가하여 해결할 수있는이 특별한 경우 “3.1: Why does $var where var="foo bar" not do what I expect?”

: 여기

은 zsh을 자주 묻는 질문 항목입니다 the zsh's faq 특히 2 장과 3 장. 다른 쉘을 경험할수록 zsh의 함정을 더 많이 찾을 수 있습니다.

1

Zsh에서는 제공된 (s) 플래그 (대 IFS)로 분할하는 것이 일반적으로 더 깔끔합니다. 데이터에 대한 해결책은 다음과 같다 :

% f() { for e in ${(s.:.)1}; print $e } 
% f foo:bar:baz 
foo 
bar 
baz 

는 자세한 내용 및 관련 플래그 zshexpn(1) man 페이지에서 매개 변수 확장 섹션을 참조하십시오.

은 (난 당신이 대장 단락 지어진 값을 의미 가정합니다.)

관련 문제