众所周知,我们可以使用以下命令将错误重定向到特定文件:
./some_script 2>error_log
我正在运行多个脚本,并希望它们将错误放入一个错误文件中。
有没有办法在每个错误实例前面附加信息,例如脚本名称?这样,错误日志可以记录例如发布错误的脚本名称等。
答案1
为您的脚本创建错误日志函数。就像是:
logerr () {
printf '%s - %s - %s\n' \
"$(date '+%F:%T')" \
"$(basename "$0")" \
"$*" >&2
}
然后您可以从脚本中调用它,例如:
if false; then
: something for pass
else
logerr failed to be false
fi
而且每次使用2>error_log
都会覆盖。error_log
您需要使用2>>error_log
附加。
如果您希望能够捕获来自其他命令的错误并记录它们,您可以将如下代码组合在一起:
#!/bin/bash
logerr () {
local message=$*
if [[ ! -t 0 ]]; then
message=$(</dev/stdin)
fi
if [[ -n "$message" ]]; then
printf '%s - %s - %s\n' \
"$(date '+%F:%T')" \
"$(basename "$0")" \
"$*" >&2
fi
}
ls -lts /fake/path 2>&1 >/dev/tty | logerr
确保将标准输出重定向到您需要的任何适用位置。
这将允许logerr
脚本从标准输入(如果它打开)读取(允许您将程序通过管道传输到 logerr)。问题是程序会将错误消息发送到 stderr,而您希望它与 stdin 保持分离。
答案2
./thescript.sh 2>&1 1>/dev/null | sed '1 s/^/error_message_starts:\n/' >> error_log;
基于此处的讨论加上以下内容:
https://stackoverflow.com/questions/2342826/how-to-pipe-stderr-and-not-stdout
以便添加我们想要的任何内容。我们需要能够通过管道传输错误流(fd2)。唯一可通过管道输出的是 fd1。所以fd2需要重定向到fd1。我们还必须摆脱 fd1,这样它就不会妨碍我们。
- ./脚本.sh
- 2>&1 错误流(fd2),转到 fd1 转到的任何位置。
- 1>/dev/null。 Fd1 刚刚跌落悬崖。现在只有错误日志(fd2)通过管道传输。
- | sed.. 在 sed 中进行管道操作,在前面添加该内容。
- >> error_log 将流附加到错误日志