while
Bash 루프의 "조건" 섹션에서 반복적으로 호출하는 함수의 종료 코드를 얻으려고 합니다 .
while <function>; do
<stuff>
done
오류로 인해 이 루프가 종료될 때 필요한 종료 코드입니다 <function>
. 그것을 얻는 방법에 대한 아이디어가 있습니까?
답변1
조건의 종료 값을 캡처하여 앞으로 전파할 수 있습니다.
while rmdir FOO; ss=$?; [[ $ss -eq 0 ]]
do
echo in loop
done
echo "out of loop with ?=$? but ss=$ss"
산출
rmdir: failed to remove 'FOO': No such file or directory
out of loop with ?=0 but ss=1
이 경우 종료 상태는 rmdir FOO
변수에 캡처되었으며 ss
입니다 1
. ( rmdir FOO
로 바꿔보세요 ( exit 4 )
. 가 표시됩니다 ss=4
.)
어떻게 작동하나요? 구문은 실제로 while list-1; do list-2; done
더 일반적인 기대가 아니라는 점을 명심하십시오 while command; do list; done
. 세미콜론으로 구분된 일련의 명령일 수 있으며 list-1
설명서에는 "while
list-2
이 명령은 목록의 마지막 명령이 종료 상태 0을 반환하는 한 list-1
목록을 계속 실행합니다 ."
혼란스러워 보이는 while
조건을 표현하는 또 다른 방법 으로 표현식 내부에 변수를 할당한 (( ... ))
후 그 결과를 사용할 수 있습니다. 이는 읽기가 더 어렵지만 보다 간결한 할당 및 테스트 구조를 제공합니다.
while rmdir FOO; ((! (ss=$?)))
do
echo in loop
done
echo "out of loop with ?=$? but ss=$ss"
또는 를 사용할 수 있습니다 while rmdir FOO; ! (( ss=$? ))
. 이는 ((1))의 산술 평가가 1이고 일반적으로 true와 연관되어 해당 평가에 대한 종료 코드가 0(성공)이기 때문에 작동합니다. 반면에 ((0))의 산술 평가는 0이며 이는 일반적으로 false와 연관되므로 이 계산의 종료 코드는 1(실패)입니다. 두 평가가 모두 "성공"한 후에 혼란스러워 보일 수 있지만 bash의 성공/실패 종료 코드와 일치하는 true/false를 나타내는 산술 표현식의 값을 만들고 , 등 ((.))
의 조건식을 기반으로 하는지 여부에 관계없이 만드는 것은 해킹입니다. 종료 코드나 산술 값에서는 모두 잘 작동합니다.if ...; then ...; fi
while ...; do ...; done
답변2
이를 달성하는 한 가지 방법은 테스트를 위임하는 대신 명시적으로 만드는 것입니다 while
. 따라서 다음을 수행해야 합니다.
err=0
while true
do
<function>
(( (err=$?) > 0 )) && break
<stuff>
done
echo "$err"
(선험적 무한) 루프의 시작 부분에서 조건부 명령을 "수동으로" 실행하고 종료 코드를 저장하고 확인한 후 0이 아닌 경우(실패를 나타냄) 루프를 종료합니다. 0일 때만 "실제" 루프 코드를 실행합니다.
@roaima가 지적했듯이 (( ... ))
산술 테스트 구성 내에서 변수 할당을 수행할 수 있기 때문에 구문을 "압축"할 수 있습니다.
답변3
함수의 종료 코드 결과로 변수를 설정하는 래퍼 함수를 만듭니다. 예:
e=0
# file does not exist
foo() {
rm xyz
}
baz() {
foo
e=$?
[[ $e -ne 0 ]] && return 1
return 0
}
# create a file
touch xyz
while baz; do
# first loop succeeds, the file exists
# second loop exits with error, file doesn't exists
echo in loop
done
in loop
rm: cannot remove 'xyz': No such file or directory
# then
$ echo $e
1
답변4
를 사용하면 익명 함수에서 사용할 zsh
수 있습니다 .return
() while ((1)) {
<function> || return
<stuff>
}
print $?
Bourne과 유사한 쉘의 경우 언제든지 명명된 함수를 사용할 수 있습니다.
repeat_until_fail()
while true; do
<function> || return
<stuff>
done
repeat_until_fail
echo "$?"