2010-07-14 43 views
7

這是怎麼回事?我認爲SIGINT將被髮送到前臺進程組。爲什麼SIGINT在這裏被抓到?

(我想,也許,該系統()正在運行一個外殼,其子進程創建一個新的進程組?任何人都可以證實這一點?)

% perl 
local $SIG{INT} = sub { print "caught signal\n"; }; 
system('sleep', '10'); 

然後按ctrl + d,然後按Ctrl + c,並注意「捕獲的信號」從不打印。

我覺得這是一件簡單的事情......無論如何要解決這個問題?問題是,當通過系統結果持有ctrl + c運行一堆命令,直到所有迭代完成(因爲perl永遠不會獲得SIGINT)並且相當煩人時,通過系統結果運行一堆命令...

這怎麼能解決? (我已經測試了使用fork()的直接和明白,這個工程......這是不是一個可以接受的解決方案,在這個時候)

UPDATE:請注意,這有什麼做「沉睡」只有命令需要一些任意長的時間才能運行,這比perl周圍的命令要多得多。那麼按下ctrl + c會被髮送到命令(就像在前臺進程組中那樣),並以某種方式設法永遠不會發送給perl。

回答

4

perldoc system

由於SIGINT和SIGQUIT系統, 的執行,如果你希望你的程序終止接收到這些信號的過程中被忽略,你需要安排使自己在這個基礎上做返回值。

@args = ("command", "arg1", "arg2"); 
system(@args) == 0 
    or die "system @args failed: $?" 

如果你想手動檢查系統的故障,您可以檢查所有可能的故障模式 通過檢查$?像這樣:

if ($? == -1) { 
    print "failed to execute: $!\n"; 
} 
elsif ($? & 127) { 
    printf "child died with signal %d, %s coredump\n", 
     ($? & 127), ($? & 128) ? 'with' : 'without'; 
} 
else { 
    printf "child exited with value %d\n", $? >> 8; 
} 

或者,你可以檢查的$與W *(價值{^ CHILD_ERROR_NATIVE})從POSIX模塊

+3

methinks我需要再次閱讀文檔: - /謝謝。 – dlamotte 2010-07-14 16:36:40

+1

我想補充一點,你需要檢查孩子的返回值的原因是你的shell將^ c/INT傳遞給整個進程組,給perl和兒童,在這種情況下,終止你的孩子的「睡眠10」。如果你簡單地'從另一個shell中'kill -INT $ perl_pid',perl將很高興SIG_IGNore你。 – pilcrow 2010-07-14 16:49:14

0

我不太明白你試圖在這裏實現什麼...但你嘗試簡單地比較:

perl -wle'local $SIG{INT} = sub { print "caught signal"; }; sleep 10;' 

你能解釋一下你想要去什麼樣的影響,以及你爲什麼調用shell?你能直接調用外部程序而不涉及shell嗎?

+0

請參閱我的更新部分中呼籲, 「沉睡」 無關與它做...它只是一個任意進程的佔位符。它可以很容易地與「grep東西」切換,這將永遠掛起,因爲它期待從標準輸入讀取數據。 – dlamotte 2010-07-14 16:30:50

+0

@xyld:我意識到睡眠是一個佔位符。我問你爲什麼需要調用shell,而不是直接調用你的過程。 – Ether 2010-07-14 17:06:48

+0

我並不明確,但是perl解釋器可能會將它作爲「system()」的一部分來執行。 – dlamotte 2010-07-15 15:48:30

相關問題