前置然后重定向
Prepend then redirect
我想将 stderr
重定向到用于记录目的的文件:
2>> "$logFile"
如何在每一行前添加字符串 "error: "
?
您可以使用进程替换。
2> >(awk '{print "error: " [=10=]}' >> "$logfile")
或者使用带有损坏的进程替换支持的旧 shell:
{ { prog >&3; } 2>&1 | sed 's/^/error: /' >> "$logfile"; } 3>&1
这里我们将 prog
的标准输出保存到 fd 3,将其标准错误通过管道传输到 sed,最后将 fd 3 恢复回标准输出。
另一种选择是sed
:
2> >(sed -u 's/^/error: /' >> "$logfile")
仅使用 bash 内置函数可能是不可能的,因为这种为字符串添加前缀的机制需要与流一起使用。
注意使用 gnu sed
选项 -u
(--unbuffered
) 从输入文件加载最少量的数据并更频繁地刷新输出缓冲区。
纯Bash版本:
2> >(while read -r line ; do echo "error: $line" ; done >> "$logFile")
。 . .但请注意,如果程序写入任何空字节,或者如果程序没有在最后一行之后写入换行符,这将出现错误。 (这两个问题都是可以解决的,但在某些时候我们不得不质疑仅仅避免调用 awk 或 sed 是否值得。)
由于进程替换在我使用 Bash 4.2.50 的 AIX 上存在问题,https://en.wikipedia.org/wiki/Process_substitution 的替代方法是使用 FIFO:
logFile='/tmp/stderr.log'
fifoFile='/tmp/log123.fifo'
mkfifo $fifoFile
glub 2>> $fifoFile & #the & is needed because otherwise the FIFO will block
cat $fifoFile | sed -u 's/^/error: /' >> "$logFile"
需要第三行的符号 &
,否则 FIFO 将阻塞,直到出现 reader。
另一种选择是在执行期间不预先添加任何内容,等到日志记录完成后再处理日志文件。
我想将 stderr
重定向到用于记录目的的文件:
2>> "$logFile"
如何在每一行前添加字符串 "error: "
?
您可以使用进程替换。
2> >(awk '{print "error: " [=10=]}' >> "$logfile")
或者使用带有损坏的进程替换支持的旧 shell:
{ { prog >&3; } 2>&1 | sed 's/^/error: /' >> "$logfile"; } 3>&1
这里我们将 prog
的标准输出保存到 fd 3,将其标准错误通过管道传输到 sed,最后将 fd 3 恢复回标准输出。
另一种选择是sed
:
2> >(sed -u 's/^/error: /' >> "$logfile")
仅使用 bash 内置函数可能是不可能的,因为这种为字符串添加前缀的机制需要与流一起使用。
注意使用 gnu sed
选项 -u
(--unbuffered
) 从输入文件加载最少量的数据并更频繁地刷新输出缓冲区。
纯Bash版本:
2> >(while read -r line ; do echo "error: $line" ; done >> "$logFile")
。 . .但请注意,如果程序写入任何空字节,或者如果程序没有在最后一行之后写入换行符,这将出现错误。 (这两个问题都是可以解决的,但在某些时候我们不得不质疑仅仅避免调用 awk 或 sed 是否值得。)
由于进程替换在我使用 Bash 4.2.50 的 AIX 上存在问题,https://en.wikipedia.org/wiki/Process_substitution 的替代方法是使用 FIFO:
logFile='/tmp/stderr.log'
fifoFile='/tmp/log123.fifo'
mkfifo $fifoFile
glub 2>> $fifoFile & #the & is needed because otherwise the FIFO will block
cat $fifoFile | sed -u 's/^/error: /' >> "$logFile"
需要第三行的符号 &
,否则 FIFO 将阻塞,直到出现 reader。
另一种选择是在执行期间不预先添加任何内容,等到日志记录完成后再处理日志文件。