Mat*_*oli 26 scripting error-handling
我想通过抑制通常成功的辅助命令的输出来简化脚本的输出。
但是,-q
当它们偶尔失败时,在它们上使用会隐藏输出,所以我无法理解错误。此外,这些命令将其输出记录在stderr
.
有没有办法在命令成功时才抑制它的输出?
例如(但不限于)这样的事情:
mycommand | fingerscrossed
Run Code Online (Sandbox Code Playgroud)
如果一切顺利,fingerscrossed
捕获输出并丢弃它。否则它会将其回显到标准或错误输出(无论如何)。
Ste*_*itt 41
moreutils
'chronic
命令就是这样做的:
chronic mycommand
Run Code Online (Sandbox Code Playgroud)
将吞下mycommand
的输出,除非它失败,在这种情况下会显示输出。
mik*_*erv 12
### 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))"
Run Code Online (Sandbox Code Playgroud)
那应该可以解决问题。它将每个的输出缓冲command
到一个已删除的临时文件中,然后/dev/null
根据其返回状态是否不为零将其输出虹吸到或 stderr 中。因为临时文件被提前删除,除了当前 shell 及其文件描述符上的子进程(禁止/proc/$pid/fd
具有适当权限的偷偷摸摸的窥探)之外,任何进程都无法读取它,并且在您完成后不需要清理。
也许在 linux 系统上更方便的解决方案:
divert(){
"$@" >&3 2>&3 ||
eval "cat <&3
return $?"
} 3<<"" 3<>/dev/fd/3
Run Code Online (Sandbox Code Playgroud)
......,在大多数炮弹,很像其他的,不同之处在于,你可以这样调用它:divert some simple-command with args
。小心 中的高输出命令"$@"
,尽管 for dash
,yash
,或其他一些用管道做 here-documents 的 shell - 我认为在这些 shell 中可能会填充管道缓冲区(在 linuxes 上的默认值约为 128kb),因此死锁. 不过,对于ksh
、mksh
、bash
、zsh
或 Bourne shell 来说,这不应该是一个问题——所有这些基本上与我在上面对exec
.
通常在出现错误的情况下,命令会向stderr
您输出消息,因此对于您的任务,您只需抑制stdout
mycommand > /dev/null
Run Code Online (Sandbox Code Playgroud)
我刚刚在另一个问题上找到了这个简单得多的答案:
output=`mycommand 2>&1` || echo $output
Run Code Online (Sandbox Code Playgroud)
奇迹般有效!
打造属于自己的慢性病
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
}
Run Code Online (Sandbox Code Playgroud)