전체 파이프라인에 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모든 워크플로 ID를 알려주세요. 그렇다면 해당하는 것을 사용합니다.죽이다다시 시작하기 전에 압축하라는 명령입니다.

추가적으로, 우리는날짜이 명령은 시스템이 몇 시에 무엇을 하고 있는지 보여주는 멋진 로그 파일을 출력합니다.

원천: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

관련 정보