더 읽기 쉽고 유사한 명령 목록을 더 명확하게 만들고 싶어서 약간의 터미널 루프를 만들었습니다.
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
해당 오류 메시지를 삭제합니다.)break
2>/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
부울 연산자를 사용하는 것은 일반적으로 부울 연산자를 사용하는 것보다 가독성이 떨어지지 if
만 somecommand || 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