有一个父进程,它通过fork产生multipe子进程。我希望通过父进程和子进程将日志文件分开。问题是子进程STDOUT被重定向到父日志文件以及子日志文件中。不知道我需要更改以避免子进程日志消息进入父日志文件。我也不能理解下面的setEnvironment函数创建OUT和ERR文件句柄的目的。这是一个现有代码,因此我保持原样。在父进程和子进程中,我将变量$ g_LOGFILE设置为包含不同的文件名,以便创建单独的日志文件。我也在父进程和子进程中都调用setEnvironment函数。我尝试通过在子进程中关闭STDOUT,STDERR,STDIN并调用setenvironment,但无法正常工作。
sub setEnvironment()
{
unless ( open(OUT, ">&STDOUT") )
{
print "Cannot redirect STDOUT";
return 2;
}
unless ( open(ERR, ">&STDERR") )
{
print "Cannot redirect STDERR";
return 2;
}
unless ( open(STDOUT, "|tee -ai $g_LOGPATH/$g_LOGFILE") )
{
print "Cannot open log file $g_LOGPATH/$g_LOGFILE");
return 2;
}
unless ( open(STDERR, ">&STDOUT") )
{
print "Cannot redirect STDERR");
return 2 ;
}
STDOUT->autoflush(1);
}
####################### Main Program ######################################
$g_LOGFILE="parent.log";
while ($file = readdir(DIR))
{
my $pid = fork;
if ( $pid ) {
setEnvironment();
#parent process code goes here
printf "%s\n", "parent";
next;
}
$g_LOGFILE="child.log";
setEnvironment();
#child code goes here
printf "%s\n", "child";
exit;
}
wait for @pids
Run Code Online (Sandbox Code Playgroud)
好吧,我测试了这段代码。这是我的示例代码。在我的代码中存在类似(不完全)的问题:所有消息都双重写入子日志文件。
所以我对你的问题的回答:
问题是子进程 STDOUT 被重定向到父日志文件以及子日志文件。
这是因为当您使用管道(open(STDOUT, "|tee ...
)作为基础结果打开文件时,您的进程fork()
将创建子进程,然后exec
进入您运行的程序(tee)。Forking(对于 tee)采用主进程的 STDOUT,因此tee
将写入父进程的日志文件。所以我认为你必须撤销对主进程使用 STDOUT 句柄。或者,第二种方法 - 删除使用tee
- 这是最简单的方法。
我也不明白下面的 setEnvironment 函数中创建 OUT 和 ERR 文件句柄的目的。
似乎这是有人对上述问题的担忧。您可以grep -rE '
\bERR\b' .
在代码中搜索是否使用过。可能有人想保存真实的 STDOUT 和 STDERR 以供进一步使用。
归档时间: |
|
查看次数: |
5939 次 |
最近记录: |