2016-12-14 3 views
2

timed 함수를 구현하려고합니다. 타이머가 타임 아웃하면 기능/명령을 종료해야합니다. 함수/명령이 완료되면, 타이머는 bash가 타이머가 시간 종료 될 때까지 기다리지 않아야합니다.bash에서 timed 함수를 실행하십시오.

(cmdpid=$BASHPID; \ 
    (sleep 60; kill $cmdpid 2>/dev/null) & \ 
    child_pid=$!; \ 
    ssh remote_host /users/jj/test.sh; \ 
    kill -9 $child_pid) 

test.sh는 60 초 이내에 완료 될 수도 있고 완료되지 않을 수도 있습니다. 이것은 잘 동작했다. 나는 "성공"또는 "실패"를 유저 네임 test.sh,의 결과를 얻을 때

는하지만, 나는 그것이 종료 타이머를 기다립니다 여기

result=$(cmdpid=$BASHPID; \ 
    (sleep 60; kill $cmdpid 2>/dev/null) & \ 
    child_pid=$!; \ 
    ssh remote_host /users/jj/test.sh; \ 
    kill -9 $child_pid) 

로했습니다. 나는 "kill -9 $ child_pid"가 set -x 명령을 사용하여 실행되는 것을 볼 수 있지만 kill은 실제로 하위 쉘을 죽이지는 않습니다. 별도의 스크립트에 타이머를 실행하는 것이 문제를 해결하기

+0

어떤 하위 셸에 대해 이야기하나요? 'sleep'이 끝나면,'kill $ cmdpid'는 첫 번째 서브 쉘을 죽일 것입니다 ... QUIT 신호 만 사용하면 가능합니다 (확실하지 않습니다). 내 의심 : 하위 프로세스 중 하나가 교수형에 처한 경우 QUIT 신호를 사용하여 하위 쉘을 죽일 수 있습니까? – Jdamian

+0

문제는 당신이 서브 쉘을 죽이는 것이지, 그 안에'sleep'이 아니라는 것입니다.'ps'를 보면'sleep'의 부모 PID가 0임을 알 수 있습니다. – cdarke

+1

'timeout' 명령을 알고 계십니까? 나는 휠체어를 다시 만들려고 노력하고있는 것 같다. – gilez

답변

1

한 가지 방법은, 둘 중 먼저 완료 스크립트 기타를 "죽이는"다음 (예를 들어) MainScriptTest에서 호출하지만 별도로 실행되며, MyTimerTest을 말한다.

killall MyTimerTest > /dev/null 2>&1 

MyTimerTest이 같은 수 : 당신이 맨 끝에이를 넣을 수 MainScriptTest

nohup /folder/MyTimerTest > /dev/null 2>&1 & 

: 당신이 처음에이를 넣을 수 MainScriptTest

예를 들면 다음과 같습니다 :

#!/bin/bash 
sleep 60 
killall MainScriptTest > /dev/null 2>&1 
exit 0 

참고 : 대문자와 소문자가 혼합 된 스크립트의 긴 이름 (예 : MainScriptTest)은 목적에 따라 달라 지므로 killall은 대소 문자를 구별하며이를 사용하면 안되는 것을 없앨 수 있습니다. 매우 안전하려면 더 긴 이름 (예 : MainScriptTest88888)과 같은 토큰을 추가하는 것이 좋습니다.

편집 :gilez 덕분에 누가 timeout 명령의 사용을 제안 했습니까? 이 시스템에 사용 가능한 경우, 하나는이 같은 빠른 한 - 라이너를 할 수있는 :

timeout 60 bash -c "/folder/MainScriptTest" 

timeout를 사용하면 편리합니다. 그러나 MainScriptTest이 독립 하위 프로세스 (예 : nohup /folder/OtherScript &을 호출하여)를 작성하면 timeout은 해당 하위 프로세스를 종료하지 않으며 종료가 깨끗하지 않을 것입니다.

내가 준 첫 번째 솔루션은 더 이상이지만, 예를 들어처럼 MainScriptTest에 추가하여 (당신이 원하는 또는 다른 프로세스) 그 자식 프로세스를 종료하도록 사용자 정의 할 수 있습니다 :

killall OtherScript > /dev/null 2>&1 
+0

이것은 작동하지 않았습니다. 새로운 bash 스크립트에서 실행되는 sleep은 "sleep"이라는 이름을 취하고 killall은 그것을 찾지 못했습니다 – user2647717

+0

시스템에서 문제를 복제 할 수 없습니다 - 완벽하게 작동합니다. 나는'GNU bash, version 4.3.30 (1)'을 가지고있다. 나는 당신이 문제가 뭐라고 말했는지 이해하고 있는지 확신하지 못한다. 혼자서 잠을 자다가 계속 뛰었습니까? 'MainScriptTest'와'MyTimerTest'는 어떻게 되나요? 다시 말하지만, 조사하고 싶다면 다시 설명해주십시오. - 기꺼이 원한다면 재미 있고 가능성있는 교육을받을 수 있습니다. –

+0

내가 언급 한 방식을 시도했을 때 "ps"는 ​​"MyTimerTest"대신 "sleep"을 표시했습니다. 그래서 "killall MyTimerTest"를 사용하여 스크립트를 죽일 수 없었습니다. 내가 사용하고있는 bash는 4.1.2 (1)입니다. 불행히도 나는 그것을 업그레이드 할 수 없다. – user2647717

1

일부 발견 다른 방법.

result=$(ssh $remote_host /users/jj/test.sh) & mypid=$! 
(sleep 10; kill -9 $mypid) & 
wait $mypid 
관련 문제