簡體   English   中英

perl fork()exec(),子進程變得瘋狂

[英]perl fork() exec() , child process gone wild

我正在使用Linux.shtcsh

我做了一個非常基本的forkexec ,但是在實現安全性方面需要幫助。

基本上,我的perl腳本在子進程中調用.sh腳本。 但是,當我執行Ctrl+c殺死父級時,子級會忽略該信號。

1)我如何也捕獲子進程的SIGINT

2)運行.sh腳本的子進程仍然STDOUT到xterm的屏幕。 我該如何刪除? 我當時正在考慮在后台運行腳本

 exec("shell.sh args &");  

但是還沒有測試,因為我需要弄清楚如何防止孩子先變得瘋狂。

3)父進程(perl腳本)不等待子進程(.sh腳本)。 所以我讀了很多關於孩子成為僵屍的信息 腳本完成后會發生嗎? 而且我將如何阻止它?

$pid = fork();
if($pid < 0){
    print "Failed to fork process... Exiting";
    exit(-1);
    }
elsif ($pid ==0) {
    #child process
    exec("shell.sh args");
    exit(1);
    }
else { #execute rest of parent}

但是,當我執行ctrl + c殺死父母時,孩子會忽略該信號。

信號被發送到父母和孩子兩個。

$ perl -E'
   if (my $pid = fork()) {
      local $SIG{INT} = sub { say "Parent got SIGINT" };
      sleep;
      waitpid($pid, 0);
   } else {
      local $SIG{INT} = sub { say "Child got SIGINT" };
      sleep;
   }
'
^CParent got SIGINT
Child got SIGINT

如果那個孩子忽略了它,那是因為它開始了一個新的會話,或者是因為它明確地忽略了它。

運行.sh腳本的子進程仍然STDOUT到xterm的屏幕。 我該如何刪除?

在調用exec之前,在子級中exec

open(STDOUT, '>', '/dev/null');
open(STDERR, '>', '/dev/null');

實際上,我將使用open3進行一些錯誤檢查。

open(local *CHILD_STDIN,  '<', '/dev/null') or die $!;
open(local *CHILD_STDOUT, '>', '/dev/null') or die $!;
my $pid = open3(
   '<&CHILD_STDIN',
   '>&CHILD_STDOUT',
   '>&CHILD_STDOUT',
   'shell.sh', 'args',
);

父進程(perl腳本)不等待子進程(.sh腳本)。 所以我讀了很多關於孩子成為僵屍的信息???

父級退出時或子級退出后退出時,子級將自動收割。

$ perl -e'
   for (1..3) {
      exec(perl => (-e => 1)) if !fork;
   }
   sleep 1;
   system("ps");
' ; ps
  PID TTY          TIME CMD
26683 pts/13   00:00:00 bash
26775 pts/13   00:00:00 perl
26776 pts/13   00:00:00 perl <defunct>       <-- zombie
26777 pts/13   00:00:00 perl <defunct>       <-- zombie
26778 pts/13   00:00:00 perl <defunct>       <-- zombie
26779 pts/13   00:00:00 ps
  PID TTY          TIME CMD
26683 pts/13   00:00:00 bash
26780 pts/13   00:00:00 ps
                                             <-- all gone

如果父母先於孩子退出,那沒有問題。

如果父母在孩子們離開后不久就退出了,那就沒問題了。

如果父母在孩子離開后很長一段時間退出,您將希望獲得他們的收獲。 您可以使用waitwaitpid (可能來自SIGCHLD處理程序)來執行此操作,也可以使用$SIG{CHLD} = 'IGNORE';使它們自動收獲$SIG{CHLD} = 'IGNORE'; 參見perlipc

在父線程中使用waitpid: http : //perldoc.perl.org/functions/waitpid.html

waitpid($pid, 0);

您還可以將exec的stdout重定向到/ dev / null:

exec("shell.sh args > /dev/null");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM