将 stdout 和 stderr 附加到文件

将 stdout 和 stderr 附加到文件

我有这个:

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重定向到该描述符stdoutstderr

相关内容