Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在bash中将文本追加到stderr重定向_Bash_Exec_Stderr - Fatal编程技术网

在bash中将文本追加到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将stderr重定向到一个错误日志

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
。这样所有行都会得到相同的时间戳?