2013-05-07 44 views
2

我剛剛編寫了一個shell腳本來控制模塊的啓動和停止。一切似乎都很正常,直到我發現停止命令導致出乎意料的結果。我使用命令kill -s SIGKILL -- -gpid來終止一組進程。我用的是/bin/sh運行這樣linux shell kill signal SIGKILL && KILL

/bin/sh -c "kill -s SIGKILL -- -gpid" 

其回答錯誤

 
/bin/sh: line 0: kill: SIGKILL: invalid signal specification 

然後,我/bin/bash取代/bin/sh的命令,因此命令是

/bin/bash -c "kill -s SIGKILL -- -gpid" 

該回答什麼錯誤。所以我總結了bash和sh之間的差異導致結果的解釋。但是,當我ls/bin/sh,我發現/bin/sh/bin/bash的符號鏈接,所以命令應該是相同的。

我發現命令語法kill -s SIGKILL不在推薦的語法中,推薦使用kill -s KILL

所以我取代了SIGKILL與KILL,命令

/bin/sh -c "kill -s KILL -- -gpid" 

這回答沒什麼錯誤。如上所述,任何人都可以解釋這種情況。

+0

什麼是您的發行?在我的Ubuntu 12.04上,'/ bin/sh'實際上指向'/ bin/dash'。難道在你的身上它也是'破折號'而你閱讀'bash'? – Shahbaz 2013-05-07 16:16:27

+5

當'bash'被調用爲'sh'時(例如通過符號鏈接,就像你的情況那樣),它使用sh兼容模式關閉大多數現代功能。我敢打賭'sh'正在調用'kill'的外部二進制文件,它不能識別'SIGKILL',但'bash'調用正在使用它的內建函數,而內建函數卻是。 – Kevin 2013-05-07 16:23:03

+0

@Kevin,bash是否通過檢查它的'argv [0]'來做到這一點? – Shahbaz 2013-05-07 16:33:10

回答

3

當bash被調用爲sh(例如,通過符號鏈接,如您的情況),它使用兼容模式,其中大多數現代功能都關閉。我敢打賭,sh正在調用kill的外部二進制文件,但它不能識別SIGKILL,但bash調用正在使用其內置函數,而內建函數是這樣做的。

+0

聽起來不錯。有什麼辦法可以檢查外部kill和內部kill之間的區別,或者是一些跟蹤我提到的命令執行進度的方法。 – 2013-05-08 04:05:44

+0

我發現它不能像上面描述的那樣工作,因爲你可以使用'enable -n kill'命令禁用內置的kill,然後執行'kill -s SIGKILL pid'。所以我想這裏一定有一些沒有提到的東西。 – 2013-05-17 18:20:34

2

唯一真正寫這個命令可移植的方法是指定一個信號而不是對凍結其殼事業的Unix系統的信號數量的工作方式

kill -9 -$gpid 

在90年代中期,基本上所有這些都是Linux和開源BSD。但是,SIGKILL的可靠信號是9號,並且一直如此(因爲V7如果不早的話)。

特殊說法--也不是便攜式的,在這種情況下是不必要的。

如果你想成爲一個更禮貌些吧(發送SIGTERM代替),然後使用

kill -15 -$gpid 

再次,這個數字是可靠的一路回V7。

1

這全是關於bash compatibility。快速修復使用/bin/bash,因爲sh無法識別SIGINT或其他功能。