GNU coreutils timeout
명령은 특정 스크립팅 상황에 매우 편리하여 명령이 빠르게 실행되면 명령 출력을 사용하고 시간이 너무 오래 걸리면 생략 할 수 있습니다.
timeout
POSIX 지정 유틸리티 만 사용 하는 기본 동작을 어떻게 추정 할 수 있습니까?
(나는의 조합을 포함 할 수있다 생각하고 wait
, sleep
, kill
및 그 밖의 무엇, 그러나 아마 내가 쉽게 접근 방식을 누락 알고있는 사람.)
답변
내 접근 방식은 다음과 같습니다.
-
백그라운드 프로세스 1로 명령 실행
-
백그라운드 프로세스 2로 “워치 독 타이머”실행
-
상위 쉘에서 종료 신호를 트랩하도록 핸들러 설정
-
두 프로세스가 완료 될 때까지 기다리십시오. 먼저 종료되는 프로세스는 종료 신호를 부모에게 보냅니다.
-
부모의 트랩 처리기는 작업 제어를 통해 두 백그라운드 프로세스를 모두 종료합니다 (이들 중 하나는 이미 정의에 의해 종료되었지만 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