### 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))"
To prawdopodobnie powinno załatwić sprawę. Buforuje dane wyjściowe każdego z nich command
do usuniętego pliku tymczasowego, a następnie wysysa dane wyjściowe do jednego /dev/null
lub do stderr, w zależności od tego, czy jego status powrotu nie był równy zero. Ponieważ plik tymczasowy jest usuwany przed czasem, nie może zostać odczytany przez żaden proces, ale bieżąca powłoka i jej elementy potomne na swoim deskryptorze pliku (z wyjątkiem podstępnych /proc/$pid/fd
szpiegów z odpowiednimi uprawnieniami) , i nie wymaga czyszczenia po zakończeniu .
Być może wygodniejsze rozwiązanie w systemach Linux:
divert(){
"$@" >&3 2>&3 ||
eval "cat <&3
return $?"
} 3<<"" 3<>/dev/fd/3
..., które w większości powłok, działa podobnie jak drugi, poza tym, że można nazwać to tak: divert some simple-command with args
. Strzeż wysokich poleceń wyjściowych w "$@"
, choć dla dash
, yash
lub jakieś inne pociski, które zrobienia-dokumentów z rurami - Myślę, że może to być możliwe w tych muszli wypełnić bufor rury (przy domyślnie około 128kb na dystrybucji Linksa) i tak impasu . To nie powinno być zmartwieniem ksh
, mksh
, bash
, zsh
, lub powłoka Bourne'a, choć - wszyscy ci zrobić w zasadzie to samo co ja wyraźnie powyżej exec
.