메인 스크립트가 실행 중이고 시간 제한 내에 완료되지 않으면 완료 여부에 따라 메인 스크립트에서 "뭔가를 수행하는" 두 번째 "느린 프로세스"를 시작하고 싶습니다. 참고: "느린 프로세스"가 시간 제한 이전에 완료되면 전체 시간 제한을 기다리고 싶지 않습니다.
"느린 프로세스"가 계속되어 성능에 대한 통계와 포렌식을 수집할 수 있기를 바랍니다.
나는 사용을 조사했다정지시키다, 그러나 완료되면 내 스크립트가 종료됩니다.
다음과 같은 단순화된 예를 가정해 보겠습니다.
메인 디렉토리
result=`timeout 3 ./slowprocess.sh`
if [ "$result" = "Complete" ]
then
echo "Cool it completed, do stuff..."
else
echo "It didn't complete, do something else..."
fi
느린 프로세스.sh
#!/bin/bash
start=`date +%s`
sleep 5
end=`date +%s`
total=`expr $end - $start`
echo $total >> /tmp/performance.log
echo "Complete"
여기서는 시간 초과를 사용하므로 스크립트가 종료되므로 아무 일도 일어나지 않습니다 /tmp/performance.log
. 끝내고 싶지만 3초 안에 끝나지 않더라도 다음 단계로 넘어가고 slowprocess.sh
싶습니다 .main.sh
답변1
ksh/bash/zsh 사용:
{
(./slowprocess.sh >&3 3>&-; echo "$?") |
if read -t 3 status; then
echo "Cool it completed with status $status, do stuff..."
else
echo "It didn't complete, do something else..."
fi
} 3>&1
( )에 대해 복원 할 수 있도록 원본 stdout을 fd 3( )에 복사하고 3>&1
나머지 서브쉘의 stdout은 파이프로 이동합니다.slowprocess.sh
>&3
(...)
read -t 3
또는 사용하려는 경우 timeout
(여기서 GNU를 가정 timeout
):
timeout --foreground 3 sh -c './slowprocess.sh;exit'
종료되는 것을 방지합니다 (이는 slowprocess.sh
쉘 프로세스에서 마지막 명령을 실행하여 최적화된 구현에 ;exit
필요합니다 ).sh
답변2
이는 유비쿼터스 쉘 도구만을 사용하는 솔루션입니다.
sleep
이는 느린 프로세스를 포크하고 백그라운드에서 wait
셸 내장 대기 외에 첫 번째 프로세스가 완료될 때까지 기다리면 쉽게 수행할 수 있습니다.모두첫 번째 작업뿐만 아니라 작업을 수행해야 합니다.
따라서 sleep
느린 프로세스와 백그라운드에서 a를 분기하고 둘 다 파이프를 통해 상태를 보고하고 파이프에서 나오는 첫 번째 상태를 읽도록 합니다.
fifo=$(mktemp -u) # if not on Linux, adapt to what your OS provides
mkfifo -m 600 "$fifo"
{ ./slowprocess.sh; echo z >"$fifo"; } &
sh -c 'sleep 3; echo a' >"$fifo" &
sleep_pgid=$!
read status <$fifo
case $status in
a) echo "That process is taking a long time"; read ignored <$fifo;;
z) echo "Done already"; kill -INT -$sleep_pgid;;
esac
rm "$fifo"
답변3
차단이 발생하더라도 slowprocess.sh
백그라운드에서 수행될 수 있으므로 시간 초과 후에도 실행이 계속될 수 있습니다.
에 대한 매뉴얼 페이지를 참조하여 뒤에서 signal
부터 사용할 수도 있습니다 .timeout
main.sh
timeout
timeout
안내페이지 에서 발췌
`-s SIGNAL'
`--signal=SIGNAL'
Send this SIGNAL to COMMAND on timeout, rather than the default
`TERM' signal. SIGNAL may be a name like `HUP' or a number. Also
see *Note Signal specifications::.
이 신호를 내부에서 잡아야 합니다 main.sh
.
timeout
다양한 유형의 실패에 대해서도 다양한 상태가 반환됩니다 . 다음을 활용할 수도 있습니다.
Exit status:
124 if COMMAND times out
125 if `timeout' itself fails
126 if COMMAND is found but cannot be invoked
127 if COMMAND cannot be found
the exit status of COMMAND otherwise
$?
라인이 실행된 후 변수에 나타납니다 timeout ...
.
답변4
다음은 불필요한 작업 제어 출력을 생성하기는 하지만 매우 간단한 또 다른 방법입니다. 백그라운드 프로세스 "sleep nnn"을 시작한 다음 "wait -n"을 사용하여 첫 번째 절전 프로세스와 모니터링 중인 프로세스를 기다립니다. 다음은 이 기술의 다소 서투른 예입니다(즉시 알림을 위해 "set -o 알림" 사용).
$ (for I in $(seq 10); do sleep 1; echo $I ; done) & \
more> J1=$! ; \
more> sleep 5 & \
more> J2=$! ; \
more> time wait -n $J1 $J2
[1] 288160
[2] 288161
1
2
3
4
[2]+ Done sleep 5
real 0m5.006s
user 0m0.002s
sys 0m0.004s
$ 5
6
7
8
9
10
[1]+ Done ( for I in $(seq 10);
do
sleep 1; echo $I;
done )
$
$ (for I in $(seq 3); do sleep 1; echo $I ; done) & \
more> J1=$! ; \
more> sleep 5 & \
more> J2=$! ; \
more> time wait -n $J1 $J2
[1] 288256
[2] 288257
1
2
3
[1]- Done ( for I in $(seq 3);
do
sleep 1; echo $I;
done )
real 0m3.025s
user 0m0.004s
sys 0m0.015s
$ [2]+ Done sleep 5
$