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