첫 번째 명령이 실패할 경우 Bash 파이프라인에서 두 번째 명령이 시작되지 않도록 방지

첫 번째 명령이 실패할 경우 Bash 파이프라인에서 두 번째 명령이 시작되지 않도록 방지

파이프에 관한 몇 가지 유용한 토론을 (다소간) 배운 후, 예를 들어 종료 상태를 다른 프로세스로 파이프로 가져오기그리고파이프라인의 한 프로세스가 실패하면 종료됩니다.첫 번째 명령이 실패하면 여전히 두 번째 명령을 시작하는 것을 피할 수 없습니다. 배관에 대한 필수 세부 사항을 놓치고 있습니까?

예를 들어

$ somecommand | tar -T - -czf /tmp/someProject.tar.gz

tar.gz제대로 작동하지 않고 예상되는 파일 목록 대신 일부 오류 메시지만 생성하는 경우 somecommand거의 빈 파일을 생성해서는 안 됩니다 .

답변1

예, 거기에는 배관에 관한 몇 가지 기본 세부정보가 있습니다.

파이프라인의 요점은 두 개 이상의 명령을 병렬로 실행하는 것입니다. 이렇게 하면 모든 데이터를 전체적으로 저장할 필요가 없고 모든 프로세스가 동시에 작동할 수 있으므로 시간이 절약됩니다. 정의에 따르면 이는 첫 번째 명령이 종료되기 전에 두 번째 명령이 시작되므로 첫 번째 명령의 종료 상태를 아직 사용할 수 없음을 의미합니다.

간단한 해결책은 임시 파일을 사용하는 것입니다. 데이터 자체가 아닌 파일 이름 목록만 전달하므로 여기서 저장소는 큰 문제가 되지 않습니다. 예를 들어:

tmp=$(mktemp)
if somecommand > "$tmp"; then
    tar -T - -czf /tmp/someProject.tar.gz < "$tmp"
fi
rm -f "$tmp"

또는 실제로 terdon이 언급한 것처럼 tartar 파일을 실행한 다음 실패하면 삭제하십시오. somecommand그러나 somecommand실패하기 전에 부분적이지만 중요한 파일 목록을 생성하면 삭제할 아카이브를 생성할 때 여전히 불필요한 I/O가 발생할 수 있습니다.

또한 적어도 GNU tar에는 -T명령줄 옵션처럼 보이는 따옴표와 줄을 기본적으로 처리하는 기능이 있으므로, 불쾌한 파일 이름이 있는 경우 이를 고려하거나 를 살펴보는 것이 좋습니다 --verbatim-files-from. --null다른 tar 구현에도 비슷한 문제가 있을 수 있습니다. .

답변2

파이프 명령의 성격을 오해한 것 같습니다.

명령 파이프라인에서모두병렬로 시작하라는 명령(참조여기예를 들어). 이것이 실행 중에 생성된 출력이 읽기 때문에 구성이 tar성공적으로 완료될 때까지 "대기" 할 수 없는 이유입니다 .somecommandtarsomecommand

이 상황을 완화하기 위해 채택할 수 있는 몇 가지 해결 방법이 있습니다.

  • 출력을 somecommand임시 파일에 버퍼링하고 tar종료 상태 somecommand신호가 "성공"인 경우에만 실행한 다음 삭제합니다(저장 공간이 충분한 경우에만 가능).
  • @terdon이 언급했듯이 실패하면 이 pipefail옵션을 사용하여 사용할 수 없는 파일을 삭제하세요.tar.gzsomecommand

답변3

가장 쉬운 방법은 를 사용하는 것입니다 &&. 출력도 캡처하고 싶기 때문에 먼저 리디렉션한 다음 사용할 수 있습니다.

somecommand > somefile && tar -T somefile -czf /tmp/someProject.tar.gz

then somecommand이외의 다른 것으로 종료 하면 실행이 발생하지 않습니다.exit 0tar

답변4

파이프는 이를 수행하는 방법이 아닙니다. 이 구성은 첫 번째 명령이 성공한 경우에만 &&두 번째 명령을 실행합니다 .

예를 들어 "goober"라는 파일이 없는 디렉터리의 경우:

$ ls goober | echo "done"
done
ls: cannot access 'goober': No such file or directory
$ ls goober && echo "done"
ls: cannot access 'goober': No such file or directory

귀하의 예에서 :

$ somecommand && tar -T - -czf /tmp/someProject.tar.gz

somecommand실패 하면 tar실행되지 않습니다.

관련 정보