现在我正在使用exec将stderr重定向到带有

的错误日志
exec 2>> ${errorLog}

唯一的缺点是我必须以时间戳开始每次运行,因为exec只是将文本直接推送到日志文件中。有没有办法重定向stderr,但允许我向其附加文本,例如时间戳?

有帮助吗?

解决方案

这非常有趣。我问过一个非常了解bash的人,他这样告诉我:

 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

这不能完全解决你的提示未显示的问题(它会在短时间后显示,但不会实时显示,因为管道会缓存一些数据......),但会在stdout上显示输出1:1和文件一样。

唯一的问题是,我无法解决,是从一个函数执行此操作,因为这会打开一个子shell,其中exec对主程序无用...

此示例重定向stdout和stderr而不会丢失原始stdout和stderr。 stdout处理程序中的错误也会记录到stderr处理程序中。文件描述符保存在变量中,并在子进程中关闭。 Bash注意不要发生碰撞。

#! /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版本,但要感谢 Shellshock ,可以依赖这就是现在。

我只是在找同样的小东西。在看到这篇文章后,我看到了另一种看起来很有希望的方法: http: //utcc.utoronto.ca/~cks/space/blog/unix/PipingJustStderr

cat q23123  2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file 
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top