### 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))"
Isso provavelmente deve funcionar. Ele armazenará em buffer a saída de cada command
um em um arquivo temporário excluído e, posteriormente, desviará a saída para /dev/null
stderr, dependendo de seu status de retorno não ser zero. Como o arquivo temporário é excluído antecipadamente, ele não pode ser lido por nenhum processo, exceto pelo shell atual e seus filhos em seu descritor de arquivo (barrando /proc/$pid/fd
bisbilhoteiros sorrateiros com permissões apropriadas) , e não requer limpeza durante o processo.
Talvez uma solução mais conveniente em sistemas Linux:
divert(){
"$@" >&3 2>&3 ||
eval "cat <&3
return $?"
} 3<<"" 3<>/dev/fd/3
... que, na maioria das conchas, funciona muito como o outro, exceto que você pode chamá-lo assim: divert some simple-command with args
. Cuidado com os comandos de alta saída "$@"
, porém, para dash
, yash
ou alguns outros shells que aqui documentam com pipes - acho que nesses shells pode ser possível preencher o buffer do pipe (com um padrão de cerca de 128 kb em linuxes) e, portanto, um impasse . Isso não deve ser uma preocupação para ksh
, mksh
, bash
, zsh
, ou o shell Bourne, embora - todos aqueles fazem basicamente a mesma coisa que eu fiz explicitamente acima com exec
.