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