첫 번째 명령이 성공할 때까지 두 번째 명령을 진행하지 않으려면 임시 파일을 사용해야합니다. 그 간단한 버전은 다음과 같습니다.
tmp=${TMPDIR:-/tmp}/mine.$$
if ./a > $tmp.1
then
if ./b <$tmp.1 >$tmp.2
then
if ./c <$tmp.2
then : OK
else echo "./c failed" 1>&2
fi
else echo "./b failed" 1>&2
fi
else echo "./a failed" 1>&2
fi
rm -f $tmp.[12]
'1> & 2'리디렉션은 '> & 2'로 축약 될 수도 있습니다. 그러나 이전 버전의 MKS 셸은 앞의 '1'없이 오류 리디렉션을 잘못 처리했기 때문에 오랫동안 안정성을 위해 모호하지 않은 표기법을 사용했습니다.
방해하면 파일이 유출됩니다. 방폭형 (약간) 쉘 프로그래밍은 다음을 사용합니다.
tmp=${TMPDIR:-/tmp}/mine.$$
trap 'rm -f $tmp.[12]; exit 1' 0 1 2 3 13 15
...if statement as before...
rm -f $tmp.[12]
trap 0 1 2 3 13 15
첫 번째 트랩 행은 rm -f $tmp.[12]; exit 1
신호 1 SIGHUP, 2 SIGINT, 3 SIGQUIT, 13 SIGPIPE 또는 15 SIGTERM이 발생할 때 '명령 실행' ' 이라고 말 하거나 0 (어떤 이유로 든 쉘이 종료되는 경우)입니다. 쉘 스크립트를 작성하는 경우 최종 트랩은 쉘 종료 트랩 인 0의 트랩 만 제거하면됩니다 (프로세스가 종료 되려고하므로 다른 신호는 그대로 둘 수 있습니다).
원래 파이프 라인에서는 'a'가 완료되기 전에 'c'가 'b'에서 데이터를 읽는 것이 가능합니다. 이는 일반적으로 바람직합니다 (예를 들어 여러 코어가 수행 할 작업을 제공함). 'b'가 '정렬'단계이면 적용되지 않습니다. 'b'는 출력을 생성하기 전에 모든 입력을 확인해야합니다.
실패한 명령을 감지하려면 다음을 사용할 수 있습니다.
(./a || echo "./a exited with $?" 1>&2) |
(./b || echo "./b exited with $?" 1>&2) |
(./c || echo "./c exited with $?" 1>&2)
이것은 간단하고 대칭 적입니다. 4- 파트 또는 N- 파트 파이프 라인으로 확장하는 것은 간단합니다.
'set -e'를 사용한 간단한 실험은 도움이되지 않았습니다.
&&|
"이전 명령이 성공한 경우에만 파이프를 계속하십시오"를 의미하는 것과 같은 것이 필요합니다 .|||
"이전 명령이 실패하면 파이프를 계속하십시오"(그리고 Bash 4와 같은 오류 메시지를 파이프 할 수 있음) 를 의미 할 수도 있습니다|&
.