### 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))"
Das sollte wahrscheinlich den Trick machen. Es puffert die Ausgabe von jedem command
in eine gelöschte temporäre Datei und siphoniert danach seine Ausgabe in entweder /dev/null
oder stderr, abhängig davon, ob sein Rückgabestatus nicht Null war oder nicht. Da die temporäre Datei vor der Zeit gelöscht wird, kann sie nicht von einem Prozess gelesen werden , aber die aktuell Shell und seine Kinder auf seiner Dateideskriptor (abgesehen von hinterhältigen /proc/$pid/fd
Snoops mit dem entsprechenden Berechtigungen) , und es erfordert keine Reinigung , wenn Sie fertig sind.
Vielleicht eine bequemere Lösung für Linux-Systeme:
divert(){
"$@" >&3 2>&3 ||
eval "cat <&3
return $?"
} 3<<"" 3<>/dev/fd/3
... , die in den meisten Schalen, ähnlich wie die andere arbeitet, mit der Ausnahme , dass Sie es wie nennen kann: divert some simple-command with args
. Hüten Sie sich vor hohen Ausgabebefehlen in "$@"
, wenn auch für dash
, yash
oder einige andere Schalen , die mit Rohren hier-Dokumente zu tun - ich denke , es ist in diesen Schalen möglich sein kann , den Rohrpuffer zu füllen (bei einer Standard von rund 128kb auf Linuxen) und so Deadlock . Das ist nicht eine Sorge für sein sollte ksh
, mksh
, bash
, zsh
, oder die Bourne - Shell, obwohl - all jene tun im Grunde das Gleiche wie ich ausdrücklich oben mit exec
.