백그라운드에서 명령을 실행할 때 시간 초과 종료 코드를 어떻게 얻을 수 있나요?

백그라운드에서 명령을 실행할 때 시간 초과 종료 코드를 어떻게 얻을 수 있나요?

ping 명령에 대한 시간 초과 값을 설정하는 동안 백그라운드에서 ping 명령을 실행하기 위한 쉘 스크립트를 작성 중이며 시간 초과로 인해 ping이 종료되면 종료 코드를 가져오고 싶습니다. 다음을 사용하고 있습니다.

timeout 10s ping -c 5 www.google.com | awk '{print "from local to google |", $0;}' &
exit_status=$?
echo $exit_status

그러나 반환된 종료 코드는 "&"이고 명령이 시간 초과되는 대신 백그라운드에서 실행되고 있음을 발견했습니다.

시간 초과 종료 코드를 어떻게 얻을 수 있나요?

답변1

여기에는 많은 문제가 있습니다. 먼저 timeouta를 매개변수로 사용하세요.단일 명령. 그래서 글을 쓸 때

timeout 10s ping -c 5 www.google.com | awk '{print "from local to google |", $0;}'

무슨 일이 일어나는지는 대략 다음과 같습니다.

( timeout 10s ping -c 5 www.google.com ) | awk '{print "from local to google |", $0;}'

즉 , 전체 파이프가 아니라 timeoutkill ping이므로 파이프의 종료 코드(즉, 의 종료 코드 awk)를 얻습니다.

종료 코드를 얻으려면 timeout서브쉘이 필요합니다. 그러나 timeout단일 명령을 매개변수로 사용하므로 명시적으로 작성해야 합니다.

timeout 10 sh -c 'ping ... | awk ...' sh

awk또는 파이프라인(예: ) 의 마지막 명령 시간을 계산할 수도 있습니다 .

ping ... | timeout 10 awk ...

이는 에서는 잘 작동 ping | awk하지만 다른 명령에서는 경쟁 조건이 발생할 수 있습니다. ping많은 출력이 생성되면 리스너를 종료하는 데 사용되는 SIGPIPE를 받을 수도 있습니다 .

귀하의 질문으로 돌아가서, 이 모든 것을 백그라운드에 두고 싶습니다. 백그라운드 명령의 종료 코드를 얻으려면 다음을 수행해야 합니다 wait.

timeout 10 sh -c 'ping ... | awk ...' sh &
wait $!
echo $?

불행히도 백그라운드에서 명령을 실행하는 목적을 무효화하는 bashasync 는 없습니다 . wait그러나 이 전에 다른 명령을 실행할 수 있습니다 wait.

관련 정보