Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Shell 重定向到日志文件时,如何在stdout和stderr输出前加上时间戳?_Shell_Logging_Pipe_Stdout_Init - Fatal编程技术网

Shell 重定向到日志文件时,如何在stdout和stderr输出前加上时间戳?

Shell 重定向到日志文件时,如何在stdout和stderr输出前加上时间戳?,shell,logging,pipe,stdout,init,Shell,Logging,Pipe,Stdout,Init,在Linux中,我在初始化脚本(SysVInit)中启动一个名为$cmd的程序。我已经将$cmd的stdout和stderr重定向到两个不同的日志文件中,分别称为$stdout\u log和$stderr\u log。现在,我还想在打印到日志文件中的每一行前面添加一个时间戳 我尝试编写一个名为log_pipe的函数,如下所示: log_管道(){ 边读边做 echo[$(日期+%Y-%m-%d\%H:%m:%S)]“$行” 完成 } 然后将我的脚本的输出导入该函数,然后将它们重定向到日志文件,

在Linux中,我在初始化脚本(SysVInit)中启动一个名为
$cmd
的程序。我已经将
$cmd
的stdout和stderr重定向到两个不同的日志文件中,分别称为
$stdout\u log
$stderr\u log
。现在,我还想在打印到日志文件中的每一行前面添加一个时间戳

我尝试编写一个名为log_pipe的函数,如下所示:

log_管道(){
边读边做
echo[$(日期+%Y-%m-%d\%H:%m:%S)]“$行”
完成
}
然后将我的脚本的输出导入该函数,然后将它们重定向到日志文件,如下所示:

$cmd | log_pipe>>“$stdout_log”2>>“$stderr_log”&
我得到的是一个空的
$stdout.log
(stdout),应该可以,因为
$cmd
通常不会打印任何内容。和一个
$stderr.log
文件,该文件只带有时间戳,但没有错误文本

我的错误推理在哪里


PS:由于init脚本中存在问题,我只想使用基本shell命令,不想使用额外的包。

在Bash中,您还可以使用进程替换重定向到子shell:

logger.sh

#!/bin/bash
while read -r line; do
   echo "[$(date +%Y-%m-%d\ %H:%M:%S)] $line"
done
重定向

cmd > >(logger.sh > stdout.log) 2> >(logger.sh > stderr.log)

在任何POSIX shell中,请尝试:

{ cmd | log_pipe >>stdout.log; } 2>&1 | log_pipe >>stderr.log
此外,如果您有GNU awk(有时称为
gawk
),则
log\u pipe
可以变得更简单、更快:

log_pipe() {  awk '{print strftime("[%Y-%m-%d %H:%M:%S]"),$0}'; }
例子 例如,让我们创建命令
cmd

cmd() { echo "This is out"; echo "This is err">&2; }
cmd() { echo "This is out"; echo "This is err">&2; }
现在,让我们运行命令并查看输出文件:

$ { cmd | log_pipe >>stdout.log; } 2>&1 | log_pipe >>stderr.log
$ cat stdout.log
[2019-07-04 23:42:20] This is out
$ cat stderr.log
[2019-07-04 23:42:20] This is err
问题 上述命令将标准输出从
cmd
重定向到
log\u pipe
log\u-pipe
的标准输出被重定向到
$stdout\u-log
log\u-pipe
的标准输出被重定向到
$stderr\u-log
问题是
cmd
的stderr永远不会被重定向。它直接通向终点站。

作为一个例子,考虑这个<代码> CMD< /代码>:

cmd() { echo "This is out"; echo "This is err">&2; }
cmd() { echo "This is out"; echo "This is err">&2; }
现在,让我们运行命令:

$ cmd | log_pipe >>stdout.log 2>>stderr.log
This is err

我们可以看到,
这是错误
没有发送到文件stderr.log。相反,它出现在终端上。
log\u pipe
从未看到它
stderr.log
仅从
log\u管道

捕获错误消息这是可行的,但我的命令必须在后台运行,因为它在初始化脚本中,因此我必须执行以下操作:

({cmd | log_pipe>>stdout.log;}2>&1 | log_pipe>>stderr.log)&
echo$!>“$pid_文件”
对吧?


但是我认为在这种情况下,$pid_文件中的pid不是$cmd的pid…

这是可行的,但是我的命令必须在后台运行,因为它在init脚本中,因此我必须执行:
bash({cmd log_pipe>>stdout.log;}2>&1|log_pipe>>stderr.log)&echo$!>“$pid_文件”
对吗?但是我认为在这个例子中,$pid_文件中的pid不是$cmd的pid……是的,这是正确的。尝试<代码>({CMD*LogyPuxe:StdOut.log;} 2>1 } LogyPuxe> STDRR.log)和PGRIPCMD>“$PIDYFILE”< /代码>。您考虑过“TS”命令吗?坦率地说,没有必要使用log_pipe()程序,因为unix/linux已经有了“ts”命令,它可以完成您想要做的事情。做“$MANTS”看看你是否满意。e、 g用法:“$cmd 2>&1 | ts'[%Y-%m-%d%H:%m:%S%Z]'| tee/your path/outputs.log>/dev/null 2>&1&”