2011-05-27 70 views
4

我有一個bash shell腳本S1,它同步啓動另一個shell腳本S2(僅包含sleep 20),即在前臺。通過發送信號在後臺停止shell腳本

我想是這樣的:

當我送SIGTERM或SIGINT到S1,既S1S2應該停止。

實際上,如果我在前臺命令行上啓動S1,並且按CTRL-C(不管是否明確地捕獲腳本中的SIGINT),它都可以工作。

當我開始在後臺S1,然後用kill -s SIGINT $!它需要發送SIGINT信號直到S2終止其正常的處理,即S2不中斷。

我的使用案例是後者,我需要一種方法來通過發送一個信號S1S2只需S1

+0

尋找'[unix] SIGINT'返回了許多有希望的答案。特別是http://stackoverflow.com/questions/4042201/how-does-sigint-relate-to-the-other-termination-signals。祝你好運。 – shellter 2011-05-27 14:39:50

回答

2

S1.sh:

#!/bin/sh 

on_term() 
{ 
    echo "S1: Sending TERM to S2.sh" 
    pkill -TERM S2.sh 
    echo "S1: Waiting for S2 to complete..." 
} 

trap "on_term" TERM 

echo "S1: Forking a child..." 

./S2.sh & 

while [ 1 == 1 ]; do 
    wait 
    if [ $? -eq 0 ]; then 
     break 
    fi 
done 

echo "S1: Done!" 

S2.sh:

#!/bin/sh 

on_term() 
{ 
    echo "S2: Terminating..." 
    exit -1 
} 

trap "on_term" TERM 

echo "S2: Sleeping..." 

sleep 5 

echo "S2: Done!" 

玩得開心!

+0

您應該使用'$!'而不是關閉具有特定名稱的進程。 – jilles 2011-05-27 10:53:25

+0

嗯,這只是一個例子;) – 2011-05-27 11:19:45

+0

當然,在後臺開始S2是一個解決方案。但是,如果不在後臺啓動S2,我可以達到相同的效果嗎?爲什麼行爲與上面描述的不同(當S1在前臺運行時ctrl-c與S1在後臺啓動時的「kill -s SIGINT」)? – Armin 2011-05-27 11:41:07

2

如果從命令行啓動S1,則使用以%開頭的作業規範(例如kill -INT %+)將信號發送到進程組中的所有進程。

如果從另一個腳本S3開始S1,或許應該用S1S2SIGINT終止,從而減少上述情況。否則,你可以嘗試使用像

set -m 
S1 & 
set +m 
pid=$! 
... 
kill -INT -- -$pid 

作業控制,但是這可能不是所有的炮彈可靠地工作,或者如果沒有控制終端。按照Ilya的答案手動轉發信號是另一種選擇。