### 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, залежно від того, чи не повернувся його статус повернення чи ні. Оскільки тимчасовий файл видаляється заздалегідь, його не можна прочитати жодним процесом, окрім поточної оболонки та її дітей у її дескрипторі файлів (забороняючи хитрі /proc/$pid/fd
соплі з відповідними дозволами) , і він не потребує очищення, коли ви закінчите.
Можливо, більш зручне рішення для систем Linux:
divert(){
"$@" >&3 2>&3 ||
eval "cat <&3
return $?"
} 3<<"" 3<>/dev/fd/3
... які, в більшості оболонок, так само, як інші працюють, за винятком того, що ви можете назвати це як: divert some simple-command with args
. Остерігайтеся високих команд виведення в "$@"
, хоча для dash
, yash
або деякі інші оболонки , які роблять тут-документи з трубами - Я думаю , що це може бути можливо в цих оболонках , щоб заповнити буфер труби (при дефолті близько 128kb на дистрибутивів Linux) і так тупику . Це не повинно бути занепокоєння для ksh
, mksh
, bash
, zsh
, або Bourne оболонки, хоча - все ті роблять в основному те ж саме, що я явно вище exec
.