2010-03-26 104 views
11

我想捕獲的信號從Script-A.sh發送到Script-B.sh 所以Script-A.sh我用命令如何從腳本向腳本發送信號SIGINT? BASH

(SIGINT發送到Script-B.sh)
殺-2 $ PID_Script-B.sh

而且在Script-B.sh我捕捉信號和通話功能的清潔

陷阱 '乾淨' 2

它不起作用,取而代之的是Script-B.sh立即死亡,而不執行Clean!

我也注意到的是,如果我想從終端發送SIGINT到捕獲任何腳本,一個ctrl-c將正確逮住,但如果我通過命令kill -2 $pid_of_script

任何想法有關指定信號發送SIGINT的兩種方法(ctrl-c VS kill -2 $pid_of_script)之間的區別,以及我如何從腳本向另一個腳本發送SIGINT?

問候,

調試

回答

12

我能夠重現您報告的行爲。我的假設是,由於腳本運行一個非交互式shell(作爲腳本的子代),SIGINT,這是一個鍵盤信號,將被忽略。

info bash

後臺進程是那些進程組ID從 終端的不同;這樣的過程不受鍵盤產生的信號的影響。

我發現,如果你trapkill使用其他信號,如SIGUSR1它的工作原理。

man bash從其他信息:

通過bash的運行

非內置命令有設定爲通過從它的父殼繼承的值的信號處理程序。當作業控制無效時,除了這些繼承的處理程序外,異步命令還會忽略SIGINT和SIGQUIT。

如果bash等待命令完成並接收針對其陷阱已經設定的信號時,陷阱不會直到命令完成執行。

上SIGCHLD任何陷阱爲每個離開兒童執行。

+0

:(1)從bash的第一位看起來像一個解釋。另外,* zsh *似乎可以正常工作。 – 2010-03-27 00:35:05

+0

對不起,這個遲到的答案。你是對的,並不是所有的信號都能夠被孩子接受,但有一些。 SIGUSR1和SIGTERM一起工作,但並不是所有的bash版本,因爲我在bash 3.00.16的腳本中發現了一個段錯誤,試圖從父親發送信號給兒子!其他時候使用相同的版本,它只會忽略沒有捕捉到的信號(在兒童級別)。但是更新的版本可以正常工作並正確傳播所有信號。非常感謝您的幫助 – Debugger 2010-03-30 01:13:16

+0

好。運行scriptA外殼腳本並調用scriptB(源代碼),如「。scriptB.sh param1 param2 .. paramN」,這樣它就會清除Sig 2/INT – 2013-06-18 18:55:47

0

在腳本A:陷阱函數看起來像下面這將調用scriptA.sh中的trap_mesg()函數。 KILL信號(2/INTerrupt,5/TERMinate-default)。所有的,你所要做的就是獲得乳寧scriptB.sh進程/會話的PID一旦scriptB.sh從scriptA.sh稱爲(nohup的...... &會給你或使用ps命令)

trap_mesg() 
{ 
#...do something here for script B.. 
# i.e. 
kill -2 PID_of_ScriptB.sh_running_process_session 
sleep 10; #just in case, not reqd though. 
#show using ps -eAf|grep "scriptB" ... if null means, scriptB is gone. user is happy now. 
#...before actually exiting out... 
#show script A is exiting out as ScriptB is dead already, time for scriptA now. 
#...do something here.. 
} 

##################################### 
## Trap signals : INT, TERM. catch ## 
##################################### 
#Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script. 
trap_call=""; 

trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15 
################################## 





現在,在scriptB.sh中,執行相同/相似的操作,但僅用於scriptB陷阱作業(如調用clean)。

clean() 
{ 
echo "karoge seva to milega meva"; 
rm -fr /some/folder_file 
} 

trap_mesg() 
{ 
#...do something here JUST for script B trap message work.. 
# i.e. 
clean; 
#...do something here.. 
} 

##################################### 
## Trap signals : INT, TERM. catch ## 
##################################### 
#Set NULL/Blank value to trap_call. This variable will help in running trap_mesg only once during the life of this script. 
trap_call=""; 

trap 'if [ -z ${trap_call} ]; then trap_call="1"; trap_mesg ; fi' 2 15 
################################## 

這樣,你不要有源/內scriptA.sh稱scriptB.sh爲 「scriptB.sh ......」