13

现在我正在使用 exec 将 stderr 重定向到错误日志

exec 2>> ${errorLog}

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

4

4 回答 4

18

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

 foo() { while IFS='' read -r line; do echo "$(date) $line" >> file.txt; done; };

首先,它创建了一个从标准输入读取一行原始输入的函数,而对 IFS 的赋值使其不会忽略空白。读取一行后,它会在输出前附加适当的数据。然后你必须告诉 bash 将 stderr 重定向到该函数中:

exec 2> >(foo)

您写入 stderr 的所有内容现在都将通过 foo 函数。请注意,当您在交互式 shell 中执行此操作时,您将不会再看到提示,因为它已打印到 stderr,并且 foo 中的读取是行缓冲的 :)

于 2009-01-07T15:31:18.967 回答
1

你可以简单地使用:

exec 1> >( sed "s/^/$(date '+[%F %T]'): /" | tee -a ${LOGFILE}) 2>&1

这不会完全解决您关于提示未显示的问题(它会在短时间内显示,但不是实时的,因为管道会缓存一些数据......),但会在标准输出和中显示输出 1:1文件。

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

于 2011-08-08T14:45:04.140 回答
0

此示例重定向 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,现在人们可以依赖它。

于 2014-10-28T14:20:00.270 回答
-1
cat q23123  2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file 
于 2014-03-17T09:21:27.043 回答