perl挂在出口(closures文件句柄后)

我有一个function,(简而言之):

my $file = IO::File->new("| some_command >> /dev/null 2>&1") or die "cannot open some_command for writing: $!\n"; ... undef $file; 

现在我什至没有写任何$file 。 目前在$file中根本没有其他操作。 当我运行程序时,它不能正常退出。 我看到句柄已经closures了,但是我的程序还在等待这个过程closures。 捕获strace

 close(6) = 0 rt_sigaction(SIGHUP, {SIG_IGN}, {SIG_DFL}, 8) = 0 rt_sigaction(SIGINT, {SIG_IGN}, {SIG_DFL}, 8) = 0 rt_sigaction(SIGQUIT, {SIG_IGN}, {SIG_DFL}, 8) = 0 wait4(16861, ^C <unfinished ...> 

如果我打开相同的阅读过程,我不会看到这个问题。

我该怎么做才能让程序退出?

编辑:到目前为止的build议是使用Expect库或完成inputstream通过CTRL + D。 但是我现在不想以任何方式与程序交互。 我希望它现在完全没有任何更多的IO进行。 那可能吗?

undef $file从文件句柄中删除一个引用计数,并使其符合垃圾回收的条件。 如果$file是常规文件的句柄,并且在其他地方没有其他对文件句柄的引用,则它应该按照IO::File 。 在这种情况下, $file是一个shell命令的句柄,并且可能还有一些其他的文件句柄的内部引用,以防止它被破坏。 使用$file->close更安全,使你的意图更清晰。


关闭文件句柄时关闭命令不起作用,您需要进程ID。 如果你像这样调用了这个命令

 my ($file,$pid); $pid = open($file, "| some_command >> /dev/null 2>&1"); 

那么你可以

 kill 'TERM',$pid; 

在你的程序结束。 我不知道如何从IO::File::new的返回值中提取进程ID。

如果some_command正在等待输入,它可能会永远坐在那里等待输入。

从文档说什么,我不认为它有什么区别,但我总是做$文件 – >关闭()而不是/之前解开处理。

编辑:发送它控制D? 也许some_command是阅读tty的而不是stdin,就像passwd那样。 如果你在这个领域,我会建议寻找预期。

控制D只是简单地复制零字节读取关闭应该做一个命令行程序。

你有尝试过使用$ file-> close()而不是undef吗?

some_command是否啜饮所有的输入和处理? 比如grep? 还是提示? 比如说… chfn? 它是否会返回任何有用的信息? 像是表示完成了?

如果是后者,您可能需要阅读Expect,以便您可以与之交互。

这个丑陋的,丑陋的黑客将导致some_commandinit而不是留在你的perl的进程树中。 Perl不再有任何进程等待,管道仍然工作 – UNIX的。

 my $file = IO::File->new("| some_command >> /dev/null 2>&1 &") 

缺点:即使some_command失败,shell也会成功,所以你不会收到任何错误。

  or die "cannot open some_command for writing: $!\n"; # now useless 

如果some_command只要在stdin上得到一个EOF(并且永远不会停止从stdin读取),尽管如此,我认为这不是必须的。

 $ cat |  some_command
 ^ d

这是否挂了,你能解决吗?