如何仅在命令成功时抑制输出?

如何仅在命令成功时抑制输出?

我想通过抑制通常成功的辅助命令的输出来简化脚本的输出。

然而,-q当它们偶尔失败时,使用它们会隐藏输出,所以我无法理解错误。此外,这些命令将其输出记录在stderr.

有没有办法抑制命令的输出只要成功

例如(但不限于)这样的事情:

mycommand | fingerscrossed

如果一切顺利,fingerscrossed捕获输出并丢弃它。否则它会将其回显到标准或错误输出(无论什么)。

答案1

moreutils'chronic命令就是这样做的:

chronic mycommand

将吞掉mycommand的输出,除非失败,在这种情况下会显示输出。

答案2

我刚刚发现这个更简单的答案这另一个问题:

output=`mycommand 2>&1` || echo $output

奇迹般有效!

答案3

### do this bit once at the top of your script
divert=
exec 3<>"${divert:=$(mktmp)}" 4<>/dev/null
rm -- "$divert"; unset divert
### then do this bit as often as needed
command >&3 2>&3
cat <&3 >&"$(((RTN=$?)?2:4))"

这应该可以解决问题。它将缓冲每个的输出command到已删除的临时文件中,然后/dev/null根据其返回状态是否不为零将其输出虹吸到或 stderr 中。因为临时文件被提前删除,所以除了当前 shell 及其文件描述符上的子进程之外,任何进程都无法读取它(禁止/proc/$pid/fd具有适当权限的偷偷窥探),并且完成后不需要清理。

也许在linux系统上有一个更方便的解决方案:

divert(){
    "$@" >&3 2>&3 ||
    eval "cat <&3
          return $?"
}   3<<"" 3<>/dev/fd/3

...在大多数 shell 中,其工作方式与其他 shell 非常相似,只是您可以这样称呼它:divert some simple-command with args。请注意 中的高输出命令"$@",但对于dashyash或其他一些使用管道执行此处文档的 shell - 我认为在这些 shell 中可能会填充管道缓冲区(Linux 上默认约为 128kb)就这样陷入僵局。不过,对于kshmkshbash、或 Bourne shell 来说,这不应该是一个问题zsh- 所有这些都基本上与我在上面明确执行的操作相同exec

答案4

打造属于自己的慢性病

my_chronic() {
  tmp=$(mktemp) || return # this will be the temp file w/ the output
  "$@"  > "$tmp" 2>&1 # this should run the command, respecting all arguments
  ret=$?
  [ "$ret" -eq 0 ] || cat "$tmp"  # if $? (the return of the last run command) is not zero, cat the temp file
  rm -f "$tmp"
  return "$ret" # return the exit status of the command
}

相关内容