我想通过抑制通常成功的辅助命令的输出来简化脚本的输出。
然而,-q
当它们偶尔失败时,使用它们会隐藏输出,所以我无法理解错误。此外,这些命令将其输出记录在stderr
.
有没有办法抑制命令的输出只要成功?
例如(但不限于)这样的事情:
mycommand | fingerscrossed
如果一切顺利,fingerscrossed
捕获输出并丢弃它。否则它会将其回显到标准或错误输出(无论什么)。
答案1
答案2
答案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
。请注意 中的高输出命令"$@"
,但对于dash
、yash
或其他一些使用管道执行此处文档的 shell - 我认为在这些 shell 中可能会填充管道缓冲区(Linux 上默认约为 128kb)就这样陷入僵局。不过,对于ksh
、mksh
、bash
、或 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
}