루프의 단축키

루프의 단축키

바로가기: , 명령문 (expr1 && expr2)대신 . if ... fi루프를 통해 ,...을 생성하고 싶다면 할 수 있나요 expr1?expr2

장난감의 예는 다음과 같습니다.

$ for cond in {0,0,0}; do if [[ $cond = 0 ]]; then echo 0; else echo 1; break; fi; done && echo "true" || echo "false"
0
0
0
true

$ for cond in {0,1,0}; do if [[ $cond = 0 ]]; then echo 0; else echo 1; break; fi; done && echo "true" || echo "false"
0
1
true

첫 번째 명령문만 반환 하고 두 번째 명령문은 반환 if...fi하도록 이 명령문을 어떻게 변경할 수 있습니까 ? 내부 로 교체 하면 터미널 창이 닫힙니다.truefalseecho 1exit

답변1

루프의 종료 상태는 루프 내에서 실행된 마지막 명령의 종료 상태( echo또는 ) break이며 둘 다의 종료 상태는 일반적으로 0입니다. 따라서 조건을 저장하고 상태를 확인해야 합니다. 다음 기능을 사용하는 것이 좋습니다.

loopcheck() {
for cond in {0,1,0}; do
  if [[ $cond = 0 ]]; then
    echo 0; 
  else
    ret=$?;   # preserve exit status of test
    echo 1; 
    return $ret;  # pass it on
  fi;
done
}

loopcheck && echo "true" || echo "false"

또 다른 옵션은 $ret위와 같이 저장하고 루프 외부에서 해당 값을 확인하는 것입니다.

답변2

나는 취한다이것질문에 암시된 내용에 더 가깝기 때문에 다른 답변보다 낫습니다(유용하지만).

$ (for cond in {0,1,0}; do if [[ $cond = 0 ]]; then true; else false; exit; fi; done) && echo "true" || echo "false" false 

답변3

루프 릴레이 for name in ...의 마지막 실행 명령의 종료 상태입니다 .

break루프를 실행 하면 break 명령 자체의 종료 상태가 기본적으로 0이므로 릴레이되므로 이후의 테스트는 동일하게 for됩니다 .&&donetrue

이 문제를 해결하는 한 가지 방법은 자체 답변에서 말씀하신 대로입니다. 이것은 훌륭하고 깔끔한 쉘이며 모든 POSIX 호환 쉘에서 잘 작동합니다.

그러나 서브쉘로서 기능을 완전히 공유하지 않기 때문에 단점이 있습니다.실행 환경1 과 그 "외부" 껍질. 실행이 시작될 때 이를 상속하지만 실행이 완료될 때 "외부" 부모로 다시 "전파"하지 않습니다. 즉, 예를 들어 루프 내부에서 설정되거나 수정된 ​​모든 변수는 나중에 루프 외부에 있지 않습니다. 보다.

Bash의 경우 대안이 있습니다. 서브셸 사용을 피하고 계속 사용할 수 있지만 종료할 루프 수가 항상 유효하지 않기 때문에 break인수를 전달하여 실패하도록 강제할 수 있습니다 . Bash는 오류 메시지를 표시하지만 리디렉션하여 이를 무음으로 설정할 수 있습니다 .-1-12>/dev/null

그러나 이 동작은 POSIX와 완전히 호환되지 않는 것으로 간주됩니다 break.특수 내장, 그리고 오류를 발생시키는 "특수 내장"나가야 해비대화형껍데기(예: 스크립트).

1[…]. 변경 사항서브쉘환경은 영향을 받을 수 없습니다.껍데기실행 환경. [...]

관련 정보