在Linux中,我在一个init脚本(SysVInit)中启动了一个名为$cmd
的程序。我已经将$cmd
的stdout和stderr重定向到两个不同的日志文件,分别名为$stdout_log
和$stderr_log
。现在我还想在打印到日志文件中的每一行前面添加一个时间戳。
我尝试编写一个名为log_pipe的函数,如下所示:
log_pipe() {
while read line; do
echo [$(date +%Y-%m-%d\ %H:%M:%S)] "$line"
done
}
然后将我的脚本输出到这个函数中,然后将它们重定向到日志文件,如下所示:
$cmd | log_pipe >> "$stdout_log" 2>> "$stderr_log" &
我得到的是一个空的$stdout.log
(stdout),这应该没问题,因为$cmd
通常不打印任何东西。和一个只有时间戳但没有错误文本的$stderr.log
文件。
我的错误推理在哪里?
PS:因为问题存在于一个初始化脚本中,我只想使用基本的shell命令,没有额外的包。
4条答案
按热度按时间e1xvtsh31#
在任何POSIX shell中,尝试:
此外,如果你有GNU awk(有时称为
gawk
),那么log_pipe
可以变得更简单,更快:示例
例如,让我们创建命令
cmd
:现在,让我们运行命令并查看输出文件:
问题
上面的命令将标准输出从
cmd
重定向到log_pipe
。log_pipe
的stdout重定向到$stdout_log
,log_pipe
的stderr重定向到$stderr_log
。问题是cmd
的stderr永远不会重定向。它直接通往终点站。例如,考虑
cmd
:现在,让我们运行命令:
我们可以看到
This is err
没有发送到文件stderr.log。相反,它出现在终端上。它从未被log_pipe
看到过。stderr.log
仅捕获来自log_pipe
的错误消息。ybzsozfc2#
在Bash中,你也可以使用进程替换重定向到子shell:
logger.sh
重定向
ktecyv1j3#
这是可行的,但我的命令必须在后台运行,因为它在一个init脚本中,因此我必须这样做:
是吧?
但我认为在这种情况下,$pid_file中的pid不是$cmd的pid.
vsaztqbk4#
这是最简单的方法,我完成这一点与时间戳包括: