perl fork()exec(),subprocess狂放

我正在使用Linux.sh是在tcsh

我做了一个非常基本的forkexec ,但是我需要帮助来实现安全。

基本上我的Perl脚本在subprocess中调用.sh脚本。 但是当我Ctrl+c杀死父母时,信号被孩子忽略。

1)如何捕获subprocess的SIGINT

2)运行.sh脚本的subprocess仍然是标准输出到xterm的屏幕。 我怎样才能删除这个? 我正在考虑在后台运行脚本

  exec("shell.sh args &"); 

但还没有testing,因为我需要弄清楚如何防止孩子先疯狂。

3)父进程perl脚本)不等待subprocess(.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} 

Solutions Collecting From Web of "perl fork()exec(),subprocess狂放"

但是当我按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脚本仍然是标准输出到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 

如果父母在孩子面前退出,那就没有问题了。

如果父母在孩子不久之后离开,那就没有问题了。

如果父母在孩子之后离开了很长时间,你会想要收割他们。 你可以使用wait或者waitpid (可能来自于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");