bash 3과 4의 SIGINT 처리 차이점

bash 3과 4의 SIGINT 처리 차이점

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하고 bashSIGINT를 현재 실행 중인 명령의 프로세스 그룹에 명시적으로 전달합니다. 그러나 이것은 사용됩니다 C.

하위 프로세스 그룹을 검색하는 표준 UNIX 명령이 없기 때문에 스크립트의 일반적인 셸을 사용하여 동일한 기능을 수행할 수 없습니다.

관련 정보