Ctrl-C를 누르면 bash 스크립트가 중지되지만 스크립트에서 호출하는 PHP 스크립트는 중지하지 마십시오.

Ctrl-C를 누르면 bash 스크립트가 중지되지만 스크립트에서 호출하는 PHP 스크립트는 중지하지 마십시오.

몇 분마다 몇 개의 스크립트를 실행해야 합니다. 논리는 PHP로 만들어졌으며 훌륭하게 작동합니다. 일을 함께 유지하기 위해 아래 bash 스크립트를 만들었으며 이 스크립트도 잘 실행됩니다.

#!/bin/bash

calculaDiff() {
    DIFF=0

    while [ "$DIFF" -eq "0" ]; do
        DIFF=`php calculaDiff.php`
    done;
}

# need to calculate pending diffs
calculaDiff

# main loop
while true; do
    CAPTURA=`php capturaRelatorio.php`
    if [ "$CAPTURA" -eq "0" ]; then
        calculaDiff
    fi

    VERIFICA=`php verificaLimites.php`

done

capturaRelatorio.phpN분마다만 처리할 수 있기 때문에 스크립트 내부에는 절전 모드가 있습니다. 내가 모니터링할 수 있도록 S초 동안 잠자기 상태라는 메시지를 인쇄합니다.

이때 bash 스크립트를 호출하고 Ctrl+를 누르면 C절전 모드인 동안 bash 스크립트는 종료되지만 호출된 php 스크립트는 종료되지 않습니다. 나는 그것을 실행하는 다른 프로세스가 있다는 것을 이해합니다.

그렇다면 bash 스크립트와 모든 "하위"를 종료할 수 있는 방법이 있습니까? 아니면 이러한 스크립트를 실행하기 위해 다른 접근 방식을 사용해야 합니까?

답변1

이 답변에서 :bash - 쉘의 모든 하위 프로세스를 종료하는 방법은 무엇입니까? - 스택 오버플로.

직접적인 아이들을 죽이는 것에만 관심이 있다면 할 수 있어야합니다

pkill -P $$

-P라고

-P, --parent ppid,...
      Only match processes whose parent process ID is listed.

$$현재 프로세스의 PID를 의미합니다 .

하위 프로세스와 이들이 시작할 수 있는 모든 프로세스(손자 등)를 종료해야 하는 경우 해당 질문에 대한 다른 답변에 있는 함수를 사용할 수 있어야 합니다.

kill_descendant_processes() {
    local pid="$1"
    local and_self="${2:-false}"
    if children="$(pgrep -P "$pid")"; then
        for child in $children; do
            kill_descendant_processes "$child" true
        done
    fi
    if [[ "$and_self" == true ]]; then
        kill "$pid"
    fi
}

이와 같이

kill_descendant_processes $$ true

현재 프로세스와 모든 하위 프로세스가 종료됩니다. 아마도 트랩 핸들러에서 이것을 호출하고 싶을 것입니다. 즉, ctrl+를 누르면 c스크립트가 전송되고 SIGINT해당 신호를 포착하여 처리할 수 있습니다. 예를 들어:

trap cleanup INT

cleanup() {
    kill_descendant_processes $$ true
}

답변2

ctrl+c를 트랩하도록 bash 스크립트를 업데이트할 수 있습니다.

trap control_c SIGINT

function control_c() {
    echo "## Trapped CTRL-C"
    ps -ef | grep php | grep -v grep | awk '{ print $2 }' > php.kill
    for i in $(cat php.kill)
    do
        kill -9 $i > /dev/null
    done
    rm php.kill
}

관련 정보