通常、成功したヘルパーコマンドの出力を抑制してスクリプト出力を簡素化したいと思います。
ただし-q
、時々失敗した場合、それを使用すると出力が非表示になり、エラーを理解できません。また、これらのコマンドは出力をstderr
。
コマンド出力を抑制する方法はありますか?成功する限り?
たとえば(これに限定されない)、次のようになります。
mycommand | fingerscrossed
すべてが順調に進むと、fingerscrossed
出力をキャプチャして破棄します。それ以外の場合は、標準またはエラー出力(何でも)に反映されます。
答え1
答え2
答え3
### 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
。"$@"
しかし、for dash
、またはここでドキュメントを実行するためにパイプを使用する他のシェルの高出力コマンドに注意してくださいyash
。そのシェルでは、パイプバッファがいっぱいになる可能性があると思います。(Linuxのデフォルト値は約128kbです.)デッドロックです。しかし、これはksh
、、、、mksh
またはBourneシェルのbash
問題にならないでくださいzsh
。すべて上記で明示的に行ったのと基本的に同じですexec
。
答え4
自分だけの慢性疾患を作る
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
}