파이프된 셸 스크립트: 스크립트 종료 캡처

파이프된 셸 스크립트: 스크립트 종료 캡처

두 개의 쉘 스크립트가 있습니다. 하나는 서버에서 실행되고 일부 파일을 임시 디렉토리에 씁니다. 그런 다음 디렉토리는 tar 아카이브로 stdout으로 전송됩니다. 마지막으로(또는 중단된 경우) 임시 디렉터리를 삭제해야 합니다. 서버 스크립트(예: "~/get_dumps.sh"에 저장됨)는 다음과 같습니다.

#!/bin/sh
set -e
temp_dir=`mktemp -d`
cd $temp_dir
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE
for db in db1 db2 db3
  do
    pg_dump $db postgres > $db.sql
done
tar cJf - .
rm -r $temp_dir

다음 스크립트를 사용하여 클라이언트에서 서버 스크립트를 호출합니다.

#!/bin/sh
set -e
temp_dir=`mktemp -d`
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE
mkdir /tmp/dumps
ssh server '~/get_dumps.sh' | tar xJf - -C $temp_dir
ls $temp_dir
rm -r $temp_dir

클라이언트 스크립트를 실행하고 Ctrl-C를 누르면 클라이언트나 서버 모두에서 임시 디렉터리가 삭제되지 않습니다. 여기서는 왜 trap작동하지 않나요?

편집: 먼저 set -e.

답변1

문제는 입니다 set -e. 여러 명령이 함께 파이프되는 동안 Ctrl-c를 누르면 SIGINT가 스크립트로 전송되지 않고 다른 곳으로 전송됩니다. 이로 인해 오류가 발생하고 set -e스크립트가 직접 종료되도록 처리됩니다. 파이프가 있는 스크립트에서 안정적으로 사용하려면 set -e다음도 캡처해야 합니다 EXIT.

#!/bin/sh
set -e
temp_dir=`mktemp -d`
cd $temp_dir
trap "rm -r $temp_dir; exit" HUP INT TERM PIPE EXIT
 for db in db1 db2 db3
   do
     pg_dump $db postgres > $db.sql
done
tar cJf - .

이 경우 법선은 exit트랩에 의해 처리되므로 어쨌든 많은 상황에서 유용할 수 있습니다.

관련 정보