【发布时间】:2016-03-08 22:07:09
【问题描述】:
我有一个模拟 tee 命令的 perl 脚本,因此我可以将输出写入终端和日志文件。它的工作原理是这样的(错误检查 &c 省略)。
$pid = open(STDOUT, '-|');
# Above is perl magic that forks a process and sets up a pipe with the
# child's STDIN being one end of the pipe and the parent's STDOUT (in
# this case) being the other.
if ($pid == 0)
{
# Child.
# Open log file
while (<STDIN>)
{
# print to STDOUT and log file
}
#close log files
exit;
}
# parent
open STDERR, '>&STDOUT';
# do lots of system("...") calls
close STDERR;
close STDOUT;
exit;
这有时会挂起,并且如果您查看进程和所述进程的堆栈,总是会发现父进程挂在其中一个关闭状态,等待子进程退出,而子进程正在从文件中读取某些内容(必须是 STDIN,因为没有其他文件)。
我不知道如何处理这个问题。如果您从未连接到控制台的 shell 运行程序,问题似乎会发生 - 在普通 shell 中运行脚本可以正常工作 - 并且该脚本中最近更改的唯一代码是添加一个文件的打开/关闭只是为了触摸它(在脚本到达这个“三通”代码之前)。
以前有没有人遇到过这样的问题和/或有关于我可以做些什么来解决这个问题的建议?谢谢。
【问题讨论】:
-
分离时是否总是发生? STDOUT 是否更早地被重定向 - 在 cron-ed 命令行上还是在程序中?
-
我看不到问题所在,对我来说,无论哪种方式都可以。我用我想尝试的具体事情和我正在使用的确切代码更新了我的帖子。我正在考虑缓冲/STDIN 搞砸了。例如,最后一次打印(最后一个缓冲区)不会被刷新。