> /dev/null 2>&1") or die "cannot open s-6ren">
gpt4 book ai didi

linux - perl 在退出时挂起(关闭文件句柄后)

转载 作者:IT王子 更新时间:2023-10-29 00:49:10 33 4
gpt4 key购买 nike

我有一个函数(简而言之):

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 <unfinished ...>

如果我打开相同的进程进行读取,我看不到这个问题。

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

编辑:到目前为止的建议是使用 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 - perl 在退出时挂起(关闭文件句柄后),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1579028/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com