SIGKILL을 전체 파이프라인에 보내는 방법은 무엇입니까?

SIGKILL을 전체 파이프라인에 보내는 방법은 무엇입니까?
while true; do 
    # process substitution instead of usual pipeline to avoid waiting for all programs
    handle_input_with_timeout < <( prog1 | prog2 | prog3 )
    echo "Data stopped flowing. Trying again"
    # perminate stuck programs in previous pipeline, then try again
    sleep 5
done

멈춰서 다시 시도하는 데 필요한 리소스를 보유할 수 있는 prog1, prog2 및 prog3을 안정적으로 제거하는 방법은 무엇입니까?

Bash에서만 수행할 수 있습니까? 아니면 cgroup을 사용해야 합니까?

답변1

이는 프로세스 그룹을 사용하여 수행할 수 있습니다(권장됨).여기) 그리고 setsid새로운 것을 시작하려면:

while true; do 

    handle_input_with_timeout < <( setsid bash -c '
          printf -- "-$$" > /tmp/saved_process_group.pid
          prog1 | prog2 | prog3
          ')
    echo "Data stopped flowing. Trying again"
    kill -9 $(< /tmp/saved_process_group.pid )

    sleep 5
done

답변2

timeout다음 항목에 포함을 사용할 수 있습니다 GNU's coreutils.

timeout <time in second> bash -c "prog1 | prog2 | prog3"

예:

timeout 5 bash -c "pwd | sleep 10"

time작동하는지 확인하려면 다음을 사용하세요 .

$ time timeout 5 bash -c "pwd | sleep 10"

real    0m5.003s
user    0m0.000s
sys     0m0.000s

답변3

잘못된 파이프라인을 제어하는 ​​한 가지 기술은 잠시 후 파이프라인 프로세스 수를 계산하는 것입니다. 완료되지 않은 경우에는 압축을 풀고 다시 시작하세요.

이 예제 코드에서는 Ask를 사용합니다.세게 때리다프로세스 ID( $$변수)에 대해 다음을 사용합니다.pgrep스크립트의 모든 하위 프로세스를 찾습니다. 즉, pgrep모든 워크플로 프로세스 ID를 알려줍니다. 있는 경우 해당 항목을 사용합니다.pkill다시 시작하기 전에 스쿼시하라는 명령입니다.

또한, 우리는날짜시스템이 몇 시에 무엇을 하고 있는지 보여주는 예쁜 로그 파일을 출력하는 명령입니다.

원천:https://github.com/shavenwarthog/johntellsall/tree/master/karma/kill-pipeline


#!/bin/bash

# pipeline.sh -- start workflow; restart if jammed

while true; do

    date '+%X workflow starting'
    (sleep 30; echo gin) &
    (sleep 30; echo tonic) &

    date '+%X waiting for workflow to complete'
    sleep 5

    # count number of child procs (ie: workflow procs)
    # If there are any, kill them then restart.
    if pgrep -cP $$ > /dev/null ; then 
        date '+%X workflow jammed -- restarting; trying again'
        pkill -P $$
        sleep 2
        continue
    fi

    date '+%X workflow done!'
    break

done

테스트 실행:

워크플로 제어 스크립트 시작

$ ./pipeline.sh &

[1] 21291

02:06:39 PM workflow starting

02:06:39 PM waiting for workflow to complete

파이프라인 스크립트는 몇 초 동안 기다리지만 워크플로 프로세스는 "sleep 30"으로 시작하므로 계속 실행 중입니다.

파이프라인은 워크플로의 정체를 감지하고, 다시 시작하기 전에 불평하고 종료합니다.

02:06:44 PM workflow jammed -- restarting; trying again

./pipeline.sh: line 27: 21293 Terminated ( sleep 30; echo gin )

./pipeline.sh: line 27: 21294 Terminated ( sleep 30; echo tonic )

02:06:46 PM workflow starting

02:06:46 PM waiting for workflow to complete

이제 파이프라인이 워크플로가 완료되기를 기다리고 있습니다. 여기서는 작업자를 죽임으로써 속임수를 쓰고 수동으로 파이프라인을 완성할 것입니다.

$ pkill -f sleep

./pipeline.sh: line 27: 21363 Terminated sleep 30

./pipeline.sh: line 27: 21365 Terminated sleep 5

./pipeline.sh: line 27: 21364 Terminated sleep 30

tonic

파이프라인 스크립트는 이제 모든 작업자가 완료되었음을 확인하므로 파이프라인이 완료됩니다. 최종 로그 메시지를 작성한 다음 종료됩니다.

02:07:16 PM workflow done!

[1]+ Done ./pipeline.sh

관련 정보