Perl Script,Fork / Exec,System声称我的进程已经死亡,而实际上只有我的子进程已经死亡

时间:2009-11-17 18:58:14

标签: perl macos scripting fork

我有一个Perl脚本,它使fork / exec在后台启动另一个工具,并在另一个工具运行时监视一些文件系统更改。这似乎与预期的一样。

当我从shell(例如Bash)启动这个Perl脚本时,当然只要我的Perl脚本正在运行,shell提示就应该消失了。它将继续运行,直到预期的文件修改发生;但是不能保证文件修改可能由外部工具完成,在这种情况下外部工具将退出,但我的脚本将继续运行并且必须以某种方式处理这种情况 - 这种处理超出了问题的范围,与我的问题无关(到目前为止它甚至没有实现)。

我的问题是,一旦我的子进程死掉,Bash就会返回其提示,声称我的进程已经完成运行......这不是真的。它显然仍然在后台运行,它仍然等待文件系统修改。如果我在脚本的主循环中继续打印一些文本,即使bash已经返回到提示符,仍会打印此文本。

我无法弄清楚是什么让bash相信我的进程已经退出。我尝试在我的脚本中阻止SIGCHLD信号,我尝试关闭和/或重定向STDOUT / STDERR / STDIN(它们在fork上重复,但你永远不知道) - 没有成功。我甚至尝试过着名的“双叉”,让最终的孩子独立于我的剧本过程,同样的结果。无论我做什么,一旦我的孩子(或孙子)去世,Bash的信念就会让我的过程退出。在后台启动我的脚本(最后使用“&”)使Bash甚至告诉我进程XYZ已经完成(它在这里命名我的进程,而不是子进程,即使我的进程很幸福并且打印到终端通过STDOUT那一刻)。

如果这只是Bash的一个问题,我可能不在乎,但是应该运行我的脚本的其他第三方软件的行为方式相同。一旦我的孩子去世,他们就声称我的剧本实际上已经死了,这根本不是真的。

1 个答案:

答案 0 :(得分:1)

只是一个健全检查,你的主要程序是否正确行走?它应该遵循非零路径:

my $pid = fork;
if ($pid == 0) {
    print "Child\n";
} else {
    print "Main\n";
}

来自man fork

  

成功完成后,fork()   向子项返回值0   处理并返回进程ID   子进程到父进程   过程