터미널 명령 템플릿 루프에서 && 연산자를 사용할 수 있습니까?

터미널 명령 템플릿 루프에서 && 연산자를 사용할 수 있습니까?

더 읽기 쉽고 유사한 명령 목록을 더 명확하게 만들고 싶어서 약간의 터미널 루프를 만들었습니다.

for what in \
   cache \
   thumbs \
; do my template $what:clear; done

잘 작동하지만

my template cache:clear && my template thumbs:clear

쉽고 명확하게 배치할 수 있는 방법이 없을까요?&&이와 같은 루프로 작업하면마지막 명령 종료 코드를 확인하기 위해 루프 본문에 if/else 문을 추가하고 0이 아닌 경우 break를 호출하는 것이 복잡하지 않습니까?

조건이 충분하다면:

for what in \
   cache \
   thumbs \
; do
my template $what:clear;
if [ $? -ne 0 ]; then break; fi \
; done

답변1

당신이 사용할 수있는 set -e:

(set -e;
for what in \
   cache \
   thumbs;
do my template $what:clear; done)

set -e명령이 0이 아닌 종료 코드로 종료될 때 쉘이 종료되도록 하며, 실패는 달리 처리되지 않습니다. 위에서 my ...실패하면 서브쉘 전체가 종료되는데, 서브쉘의 종료 코드는 실패한 명령의 종료 코드이다. 이는 쉘 스크립트와 명령줄에서 작동합니다.

또 다른 방법은 분리를 사용하는 것입니다.

for what in \
   cache \
   thumbs; do
    my template $what:clear || break
done

단점은 || break모든 명령 후에 필요하며 실패를 나타내는 종료 코드를 무시한다는 것입니다. 루프는 for매번 0의 종료 코드로 종료됩니다. 종료 코드 1로 루프가 종료되도록 하는 장애 조치를 설정하여 break이를 방지 할 수 있습니다(이는 여전히 위의 하위 쉘 접근 방식보다 열등합니다).for

for what in \
   cache \
   thumbs; do
    my template $what:clear || break -1 2>/dev/null
done

( 0이 아닌 종료 코드로 종료하고 break -1해당 오류 메시지를 삭제합니다.)break2>/dev/null

내가 아는 한, &&종료 루프 같은 && done것을 사용할 수 없습니다.

답변2

오류가 발생하면 루프를 종료할 수 있는 직접적인 방법이 없습니다. 가장 확실한 방법은 while루프 대신 루프를 사용하는 것이지만 for이는 목록 반복과 쉽게 결합되지 않습니다. 목록을 변수로 조합한 다음 목록에서 요소를 명시적으로 제거해야 하므로 코드가 더 복잡해집니다.

items=(cache thumbs);
while ((${#items[@]})) && my template "${items[0]}":clear; do shift items; done
((${#items[@]} == 0)) # to check if all the items were processed

명령문을 사용하는 것보다 작성하는 더 짧은 방법 if은 다음과 같습니다.

for what in cache thumbs; do
  my template "$what":clear || break;
done

부울 연산자를 사용하는 것은 일반적으로 부울 연산자를 사용하는 것보다 가독성이 떨어지지 ifsomecommand || fallback상당히 관용적입니다.

for루프는 항상 성공합니다 . 코드가 일찍 종료되는지 알 수 있는 편리한 방법은 없습니다( $what마지막 항목이 루프 뒤에 있는지 테스트할 수 있지만 이를 위해서는 마지막 항목이 무엇인지 알 수 있는 편리한 방법이 필요하며, 마지막 항목이 성공적으로 처리되었습니다.)

이는 여러 명령에 맞게 확장되지 않습니다. 대신에 켤 수도 있습니다오류가 발생하여 종료Mode with set -e. 명령이 실패하면 쉘이 즉시 종료됩니다(간단한 경우 - 세부 사항은 매우 복잡하지만 여기서는 충분합니다). 포함하는 루프나 포함하는 함수 또는 포함하는 스크립트뿐만 아니라 전체 (하위)쉘이 종료됩니다. 스크립트의 일부만 종료하려면 해당 부분을서브쉘. 변수 수정 사항은 서브셸 전체에서 유지되지 않습니다.

( set -e;
  for what in cache thumbs; do
    my template "$what":clear;
  done
)
# Here $? is 0 if all the mv commands succeeded and nonzero otherwise

관련 정보