我有一个功能(简而言之):
my $file = IO::File->new("| some_command >> /dev/null 2>&1")
or die "cannot open some_command for writing: $!\n";
...
undef $file;
现在我甚至没有写任何文件到$file.目前,$file上根本没有其他操作.当我运行该程序时,它无法正常退出.我看到句柄已关闭,但我的程序仍在等待关闭进程.捕获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
如果我打开相同的阅读过程,我不会看到这个问题.
要使程序退出,我该怎么办?
编辑:到目前为止的建议是使用Expect库或通过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.
标签:linux,pipe,process,perl,ipc
来源: https://codeday.me/bug/20190713/1452505.html