
Bash 4.3에서는 잘 실행되는 스크립트가 있지만 Bash 3.2에서는 예상치 못한 동작이 발생합니다. 단순화된 버전은 다음과 같습니다.
set -o errexit -o pipefail
task() {
local name=${1}
local duration=${2}
trap 'echo "[${SECONDS} secs] ${name}: SIGINT"; exit 255' INT
echo "[${SECONDS} secs] ${name}: Running"
sleep "${duration}"
echo "[${SECONDS} secs] ${name}: Done"
}
trap 'echo "[${SECONDS} secs] SIGINT"; exit 255' INT
task 'Task 1' 5 &
task 'Task 2' 5 &
wait
echo "[${SECONDS} secs] Done"
다음은 bash 4.3(4.3.42(1)-release)을 사용하여 CTRL-C를 2초 동안 실행한 후의 출력입니다.
[0 secs] Task 1: Running
[0 secs] Task 2: Running
^C[2 secs] SIGINT
[2 secs] Task 2: SIGINT
[2 secs] Task 1: SIGINT
prompt>
동일하지만 bash 3.2(3.2.57(1)-릴리스)의 경우:
[0 secs] Task 1: Running
[0 secs] Task 2: Running
^C[2 secs] SIGINT
prompt> [5 secs] Task 2: Done
[5 secs] Task 1: Done
bash 3.2에서 위 스크립트가 올바르게 작동하지 못하게 하는 알려진 문제가 있습니까? 해결 방법이 있나요?
제가 시도한 몇 가지 사항은 다음과 같습니다.
상위 항목에는 신호 처리기가 없습니다.
# bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] Task 2: SIGINT [2 secs] Task 1: SIGINT prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done
신호 처리기가 전혀 없습니다.
# bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done
상위의 신호 처리기는 SIGINT()를 사용하여 프로세스 그룹을 종료합니다
kill -INT -- -$$
.[0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT [2 secs] Task 2: SIGINT [2 secs] Task 1: SIGINT prompt> [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done
상위의 신호 처리기는 SIGTERM(SIGTERM을 포착하는 작업)을 사용하여 프로세스 그룹을 종료합니다.
# bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT [2] 92813 terminated bash minimal_example.sh prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT Terminated: 15 Terminated: 15 [2 secs] Task 2: SIGTERM [2 secs] Task 1: SIGTERM [1] 92836 terminated /bin/bash minimal_example.sh prompt>
마지막 것은 3.2에서 제대로 작동하는 데 가장 가깝습니다.하지만4.3에서는 동일한 코드가 다르게 동작합니다.
답변1
귀하는 bash
종종 make
사용자에게 영향을 미치는 잘 알려진 문제의 피해자일 수 있습니다.
Bash 4를 확인하지 않았지만 bash 3
스크립트 내에서 작업 제어가 잘못 실행되고 있습니다. 이로 인해 ^C
명령이 대화형이 아니더라도 하위 프로세스가 별도의 프로세스 그룹에서 실행되기 때문에 쉽게 종료되지 않는 여러 하위 디렉터리 루프가 포함된 메이크파일이 생성되는 경우가 많습니다 .
smake
해결 방법을 포함 /bin/sh
하고 bash
SIGINT를 현재 실행 중인 명령의 프로세스 그룹에 명시적으로 전달합니다. 그러나 이것은 사용됩니다 C
.
하위 프로세스 그룹을 검색하는 표준 UNIX 명령이 없기 때문에 스크립트의 일반적인 셸을 사용하여 동일한 기능을 수행할 수 없습니다.