vir*_*tor 3 linux perl ipc pipe process
我有一个功能(简而言之):
my $file = IO::File->new("| some_command >> /dev/null 2>&1")
or die "cannot open some_command for writing: $!\n";
...
undef $file;
Run Code Online (Sandbox Code Playgroud)
现在我甚至都没有写任何东西$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 <unfinished ...>
Run Code Online (Sandbox Code Playgroud)
如果我打开相同的阅读过程,我不会看到这个问题.
要使程序退出,我该怎么办?
编辑:到目前为止的建议是使用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");
Run Code Online (Sandbox Code Playgroud)
那么你可以
kill 'TERM',$pid;
Run Code Online (Sandbox Code Playgroud)
在你的程序结束时.我不知道如何从返回值中提取进程ID IO::File::new
.
如果some_command正在等待输入,它可能会永远坐在那里等待输入.
从文档的内容来看,我认为它没有任何区别,但我总是在取消句柄之前执行$ file-> close()而不是/.
编辑:发送它控制D?也许some_command正在读取tty而不是stdin,就像passwd那样.如果你在那个领域,我建议你查看Expect.
控制D只是复制了关闭应该对命令行程序执行的零字节读取.
您是否尝试过使用$ file-> close()而不是undef?
归档时间: |
|
查看次数: |
2864 次 |
最近记录: |