在bash中将文本追加到stderr重定向
现在,我正在使用exec将stderr重定向到一个错误日志在bash中将文本追加到stderr重定向,bash,exec,stderr,Bash,Exec,Stderr,现在,我正在使用exec将stderr重定向到一个错误日志 exec 2>> ${errorLog} 唯一的缺点是每次运行都必须有一个时间戳,因为exec只是将文本直接推送到日志文件中。是否有一种重定向stderr的方法,但允许我向其添加文本,例如时间戳?这非常有趣。我问过一个非常了解巴什的人,他这样告诉我: foo() { while IFS='' read -r line; do echo "$(date) $line" >> file.txt; done; };
exec 2>> ${errorLog}
唯一的缺点是每次运行都必须有一个时间戳,因为exec只是将文本直接推送到日志文件中。是否有一种重定向stderr的方法,但允许我向其添加文本,例如时间戳?这非常有趣。我问过一个非常了解巴什的人,他这样告诉我:
foo() { while IFS='' read -r line; do echo "$(date) $line" >> file.txt; done; };
首先,这将创建一个从stdin读取一行原始输入的函数,而对IFS的赋值使其不会忽略空格。读取了一行之后,它会输出相应的数据。然后,您必须告诉bash将stderr重定向到该函数中:
exec 2> >(foo)
您写入stderr的所有内容现在都将通过foo函数。注意:在交互式shell中执行此操作时,将不再看到提示,因为它已打印到stderr,并且读入的foo是行缓冲的:)您可以简单地使用:
exec 1> >( sed "s/^/$(date '+[%F %T]'): /" | tee -a ${LOGFILE}) 2>&1
这并不能完全解决提示未显示的问题(itt将在短时间后显示,但不是实时显示,因为管道将缓存一些数据…),但将在标准输出和文件中显示1:1的输出
唯一的问题是,我无法解决的是,从一个函数执行此操作,因为这会打开一个子shell,其中exec对主程序无效…此示例重定向stdout和stderr,而不会丢失原始stdout和stderr。stdout处理程序中的错误也会记录到stderr处理程序中。文件描述符保存在变量中,并在子进程中关闭。Bash会注意,不会发生碰撞
cat q23123 2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file
#! /bin/bash
stamp ()
{
local LINE
while IFS='' read -r LINE; do
echo "$(date '+%Y-%m-%d %H:%M:%S,%N %z') $$ $LINE"
done
}
exec {STDOUT}>&1
exec {STDERR}>&2
exec 2> >(exec {STDOUT}>&-; exec {STDERR}>&-; exec &>> stderr.log; stamp)
exec > >(exec {STDOUT}>&-; exec {STDERR}>&-; exec >> stdout.log; stamp)
for n in $(seq 3); do
echo loop $n >&$STDOUT
echo o$n
echo e$n >&2
done
这需要一个当前的Bash版本,但多亏了它,现在人们可以依赖它。$foo(){while IFS=''read-r line;do echo“$(date)$line”>>file.txt;done;};$exec 2>>(foo)警告:程序“/bin/bash”崩溃。whoops但是如果我将其更改为:echo 2 | tee>(foo),那么它工作得很好。在应答中,将为每一行打开日志文件。此外,还需要在文件末尾进行搜索。最好在
foo
中执行第二次exec
。这样所有行都会得到相同的时间戳?