Answers:
moreutils
。无论如何对我来说都是好:)
### 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或stderr中。由于临时文件会提前删除,因此任何进程都无法读取它,而是当前shell及其文件描述符上的子进程(除非/proc/$pid/fd
具有适当权限的偷偷摸摸的窥探),并且在清理过程中不需要清理。
也许是在Linux系统上更方便的解决方案:
divert(){
"$@" >&3 2>&3 ||
eval "cat <&3
return $?"
} 3<<"" 3<>/dev/fd/3
...在大多数shell中,它的工作方式与其他类似,只是您可以这样称呼它:divert some simple-command with args
。当心高输出的命令"$@"
,虽然对dash
,yash
或者一些其他的壳里面做这里的文档与管道-我认为这是可能的那些壳来填充管道缓冲区(在对Linux版本各地128KB的默认值),因此僵局。这不应该是一个隐忧ksh
,mksh
,bash
,zsh
,或者Bourne shell的,虽然-所有这些基本上做同样的事情,我做了明确以上exec
。
通常在发生错误的情况下,命令会向其输出消息,stderr
因此对于您来说,您可以压制任务stdout
mycommand > /dev/null
stderr
(因此它没有任何作用)。
使自己成为慢性病
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
}
我在我的makefile文件中做了这样的事情:
if (mycommand) &> mycommand.log; then
echo success
else
c=$?;
echo;echo -e "Bad result from previous command, see mycommand.log for more details";echo;
command_to_run_on_fail
(exit $c)
fi
适应您的情况,您可以执行以下操作:
if ! (mycommand) &> mycommand.log; then
c=$?;
cat mycommand.log
rm mycommand.log
(exit $c)
fi
因此,“ if”运行命令并将输出通过管道传输到mycommand.log。如果您需要捕获stdout vs stdout vs之类的内容,则可能需要将管道命令“&>”更改为“>”。如果命令失败,则捕获错误代码,打印出mycommand.log的内容,删除mycommand.log,最后返回原始错误代码。
如果没有(exit $ c),您将返回与“ rm”命令返回的内容匹配的退出代码。
最后,如果您需要一个衬板,则可以使用类似的方法。
mycommand &> mycommand.log || cat mycommand.log; rm mycommand.log
(...)
这样呢?因为它对您没有任何帮助,但会产生额外的子外壳。
(exit $c)
正在设置$?
,否则您将无法执行此操作。if ! (mycommand) &>x
如果命令使用例如time
或会给出shell错误,则对于重定向有意义。
{ ; }
……尽管exit
在那里有些棘手,但诚然。
$?
则可以使用,exit $c
但是可以,但在其他情况下(exit $?)
还是有价值的(尽管rret() { return $1; }
我一般认为shell函数会更好)。正如mikeserv指出的那样,命令的子外壳仍然没有。