2012-03-30 38 views
1

exec'ed但我有一個Perl腳本如下設計:檢查是否分叉的孩子在Perl

my $child_pid = fork; 
if(! $child_pid){ 
    # do some stuff... 
    exec($user_specified_command); 
else{ 
    # wait for child to exit 
    waitpid($child_pid, 0); 
} 
# Continue with the script 

我很感興趣,在當孩子的高管母公司得到一個警報,以便我可以獲得關於$user_specified_command的一些詳細信息(具體來說,要使用lsof來確定stdout是否被重定向到常規文件)。其結果將是這樣的:

my $child_pid = fork; 
if(! $child_pid){ 
    # do some stuff... 
    exec($user_specified_command); 
else{ 
    # wait until the child exec's 
    wait_child_exec(); 

    # do some stuff... 

    # wait for child to exit 
    waitpid($child_pid, 0); 
} 
# Continue with the script 

我可以循環和grep ps輸出,直到名稱更改,但似乎EXEC是相當嚴重的事件,有一個更好的辦法。

+0

難道是更容易,如果你交換了孩子和父母的角色?畢竟,家長有孩子的PID,並可以在此基礎上發送信號。 – thb 2012-03-30 19:19:22

+0

如果我期望「這個」進程在exec之前發送信號,那麼操作系統是否有可能還沒有處理exec,並且我的perl可能會過早發生? – ajwood 2012-03-30 19:23:43

+0

是的,完全正確。我應該想到這一點,但沒有。所以,根據你的建議,會發生另一種想法:你能編寫一個'$ user_specified_command'的包裝嗎?包裝器會收到兩個命令行參數:首先,它會接收「this」進程的PID,以便它可以發送所需的信號;第二,它會收到'$ user_specified_command',這樣它就知道它正在包裝哪個命令。如果這不能解決時間問題,那麼我的做法就很糟糕。請指教。 – thb 2012-03-30 19:30:43

回答

2

對此的一種常規方法是在父級中創建一個由子級繼承的管道,並使父級(或輪詢)管道的讀取結束。

假設孩子有FD_CLOEXEC或者更好的$^F一個合適的值,則孩子的exec()通話將關閉管道的寫端產生EOF父:

# Run a command in a child process, returning to the parent only after 
# the child process has called exec'd or, failing that, terminated. 
# 
# WARNING - this code not rigorously tested 
# 
sub spawn_patiently { 
    my ($rd, $wr); 

    return unless pipe($rd, $wr); 
    # XXX This assumes $^F is less than fileno($wr) 
    #  In practice, you'd want it to be less than fileno($rd), too 

    my $pid = fork(); 
    return unless defined $pid; 

    if (! $pid) { 
    exec @_; 
    die "exec: $!"; 
    } 

    # parent - wait for child to exec 
    close($wr); 
    read($rd, my $dummy, 1); 

    1; 
} 
相關問題