我有一个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_command
被init
而不是留在你的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
这是否挂了,你能解决吗?