GNU coreutils timeout
명령은 특정 스크립팅 상황에서 매우 편리합니다. 명령이 빠르게 실행되는 경우 명령의 출력이 소비되도록 허용하거나 명령을 실행하는 데 너무 오래 걸리는 경우 이를 건너뜁니다.
timeout
POSIX 사양만을 사용하여 유틸리티의 기본 동작을 어떻게 대략적으로 계산할 수 있습니까 ?
wait
sleep
(나는 그것이 , , 의 조합을 포함할 수 있다고 생각했고 또 무엇을 아는지 알 수 없지만 kill
더 쉬운 방법을 놓쳤을 수도 있습니다.)
답변1
내 접근 방식은 다음과 같습니다.
백그라운드 프로세스 1로 명령 실행
백그라운드 프로세스 2로 "watchdog 타이머" 실행
상위 셸에서 종료 신호를 포착하도록 핸들러를 설정합니다.
두 프로세스가 모두 완료될 때까지 기다립니다. 먼저 종료되는 프로세스는 상위 프로세스에 종료 신호를 보냅니다.
상위 프로세스의 트랩 핸들러는 작업 제어를 통해 두 백그라운드 프로세스를 모두 종료합니다(프로세스 중 하나가 정의에 따라 종료되었지만 PID를 사용하지 않기 때문에 종료는 무해합니다. 아래 참조).
나는 시스템 PID 대신 종료할 백그라운드 프로세스를 식별하기 위해 쉘의 작업 제어 ID(이 쉘 인스턴스에 명시적으로 명시되어 있음)를 사용하여 주석에 언급된 가능한 경쟁 조건을 회피하려고 합니다.
#!/bin/sh
TIMEOUT=$1
COMMAND='sleep 5'
function cleanup {
echo "SIGTERM trap"
kill %1 %2
}
trap cleanup SIGTERM
($COMMAND; echo "Command completed"; kill $$) &
(sleep $TIMEOUT; echo "Timeout expired"; kill $$) &
wait
echo "End of execution"
결과 TIMEOUT=10
(워치독 이전에 명령이 종료됨):
$ ./timeout.sh 10
Command completed
SIGTERM trap
End of execution
결과 TIMEOUT=1
(명령 전에 워치독이 종료됨):
$ ./timeout.sh 1
Timeout expired
SIGTERM trap
End of execution
결과 TIMEOUT=5
(워치독과 명령이 "거의" 동시에 종료됨):
./tst.sh 5
Timeout expired
Command completed
SIGTERM trap
End of execution