【发布时间】:2020-03-02 06:57:37
【问题描述】:
我想将stderr 重定向到一个用于记录目的的文件:
2>> "$logFile"
如何将字符串 "error: " 添加到每一行?
【问题讨论】:
标签: bash pipe io-redirection
我想将stderr 重定向到一个用于记录目的的文件:
2>> "$logFile"
如何将字符串 "error: " 添加到每一行?
【问题讨论】:
标签: bash pipe io-redirection
另一个选项是sed:
2> >(sed -u 's/^/error: /' >> "$logfile")
可能无法仅使用 bash 内置函数,因为这种为字符串添加前缀的机制需要与流一起使用。
注意使用gnu sed 选项-u (--unbuffered) 从输入文件中加载最少量的数据并更频繁地刷新输出缓冲区。
【讨论】:
while 循环更有效
$logfile 中的每一行前加上"error: " 前缀,它在我的测试中确实有效
您可以使用进程替换。
2> >(awk '{print "error: " $0}' >> "$logfile")
或者使用支持损坏进程替换的旧外壳:
{ { prog >&3; } 2>&1 | sed 's/^/error: /' >> "$logfile"; } 3>&1
在这里,我们将prog 的标准输出保存到 fd 3,将其标准错误通过管道传输到 sed,最后将 fd 3 恢复到标准输出。
【讨论】:
awk 的情况下仅使用 bash 内置函数来做到这一点?
exec >&3 我会收到错误“3:错误的文件描述符”纯 Bash 版本:
2> >(while read -r line ; do echo "error: $line" ; done >> "$logFile")
。 . .但请注意,如果程序写入任何空字节,或者程序没有在最后一行之后写入换行符,这将出现异常。 (这两个问题都是可以解决的,但在某些时候我们不得不质疑是否值得仅仅为了避免调用 awk 或 sed。)
【讨论】:
由于在我的 AIX 上使用 Bash 4.2.50 进行进程替换存在问题,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 将阻塞,直到有读取器为止。
另一种选择是在执行期间不添加任何内容,等到日志记录完成后再处理日志文件。
【讨论】:
{ { glub >&3; } 2>&1 | sed 's/^/error: /' >> "$logfile"; } 3>&1 也应该可以正常工作