![将 stdout 和 stderr 附加到文件](https://linux22.com/image/158625/%E5%B0%86%20stdout%20%E5%92%8C%20stderr%20%E9%99%84%E5%8A%A0%E5%88%B0%E6%96%87%E4%BB%B6.png)
我有这个:
nohup_ntrs(){
nohup_file="$HOME/teros/nohup/stdio.log"
mkdir -p "$(dirname "$nohup_file")";
echo " ------------- BEGIN $(date) -------------- " >> "$nohup_file"
nohup "$@" &>> "$nohup_file"
echo " ------------- END $(date) -------------- " >> "$nohup_file"
}
但这个语法是错误的:
nohup "$@" &>> "$nohup_file"
我试图使用 >> 运算符进行追加,但也将 stderr 发送到那里。我的猜测是,做到这一点的唯一方法是:
nohup "$@" 2>&1 >> "$nohup_file"
有没有更简洁的方法来做到这一点?
答案1
&>>
bash
是shell 中将标准输出流和标准错误流重定向到附加模式文件的正确语法。
我认为可能发生的情况是您使用运行脚本sh
,而在您的系统上不是bash
。或者,您正在运行bash
早于版本 4.0 的版本,这是第一个支持&>>
.
另一种符合标准的方法是使用>>file 2>&1
.就你而言,
nohup "$@" >>"$nohup_file" 2>&1
没有更短在符合标准的 shell 中执行此操作的方法sh
。
请注意,您的建议2>&1 >>file
是从后到前,不会将标准错误流发送到文件,而是发送到标准输出流的任何位置起初去。重定向以从左到右的方式处理,因此你的重定向首先会将标准错误发送到标准输出所在的位置,并且然后以附加模式将标准输出重定向到文件。换句话说:第二个重定向>>file
不会改变标准错误的去向,因此它会去往标准输出最初去往的位置(由于前面的2>&1
.
编写代码的另一种方法是
nohup_ntrs () {
nohup_file="$HOME/teros/nohup/stdio.log"
mkdir -p "$(dirname "$nohup_file")"
{
printf ' ------------- BEGIN %s -------------- \n' "$(date)"
nohup "$@"
printf ' ------------- END %s ---------------- \n' "$(date)"
} >>"$nohup_file" 2>&1
}
通过将输出应重定向到大括号中的命令分组并重定向该命令,可以将重定向次数减少到单个重定向次数复合命令作为一个整体。
答案2
nohup "$@" 2>&1 | tee "$nohup_file"
或者您可以在脚本中打开文件描述符,并将两者exec
重定向到该描述符stdout
stderr