私は多くの非対話型スクリプトを書いて、すべての出力がログファイルに移動し、画面に何も表示されないことを望みます。
この問題を解決するために、私は以下を使用しました。
#!/bin/bash
exec &> logfile
echo "Step One:"
/some/command/one
echo "Step Two:"
/some/command/two
これが合理的なアプローチであることを確認したいと思います。
このアプローチを引き続き使用すると、大きな欠点や問題が発生しますか?もしそうなら、それが何であり、それを軽減する最善の方法(アプローチの変更を含む)。
ベストアンサー1
コマンド出力をログファイルにリダイレクトする
非対話型シェルスクリプトがすべてのコマンド出力(エラーメッセージを含む)をログファイルにリダイレクトするのは標準的な方法です。 cron によって実行される、または他の外部イベントによってトリガされるスクリプトのコマンド出力をログに記録することは特に有用であり、これらのユースケースでは欠点はありません。
私のシェルスクリプトのほとんどは、始めに次の行を含みます。
exec 1>>"$logfile"
exec 2>&1
これらのリダイレクトコマンドの順序は重要です。最初のコマンドは、(1)ストリームexec
へのすべての書き込みをログファイルに追加()するようにリダイレクトします。 2 番目のコマンドは、(2) ストリームへのすべての書き込みを、現在の (1) が指す同じファイル記述子にリダイレクトします。 1 つのファイル記述子のみを使用してファイルにアクセスすると、必要な順序で書き込みが行われます。stdout
>>
stderr
stdout
Bashを使用している場合は、これらのコマンドを同じ操作を実行する構造に組み合わせることができます。
exec &>>"$logfile"
スクリプトを実行するたびにログファイルの前のエントリを消去するには、単一の>
リダイレクト演算子のみを使用します(以前の内容を上書き)。
exec &>"$logfile"
exec
組み込み関数を使用した入出力リダイレクトは、POSIX定義によって指定されます。シェルコマンド言語、 exec
組み込み機能はすべてのPOSIX準拠シェルで使用できます。
対話型シェル実行時のリダイレクト
一時/使い捨ての対話型シェルセッションで標準出力をファイルにリダイレクトできます。を実行すると、その後のすべてのコマンドが端末の代わりに端末exec 1>outfile
に出力を印刷します。outfile
対話型シェルセッション内で標準エラーリダイレクトを試みることもできますが、これにより対話型シェルセッションを使用するのが非常に困難になる可能性があります。
を実行した後、exec 2>errorfile
他のコマンドによって生成された標準エラーは、期待どおりにリダイレクトされたエラーファイルに書き込まれます。しかし問題はこれから、シェル(この場合はBash)はプロンプトをこのファイルに出力し、コマンドで入力されたすべてのテキストもこのファイルにリダイレクトされます。一部のシェル(Bashなど)は、受信したstdin
文字をエコーしますstderr
。たとえば、dash
シェルセッションの残りの部分では何も端末に送信されないため、基本的に盲目的に動作します。これは明らかにとても難しいシェルと引き続き対話します。
〜のようにオリオンは以下を指す。そしてスコットが言う、これらの実験をそれぞれ使用して試す前に、基本記述子とファイル記述子へのstdout
参照を保存できます。実験が完了したら、次を実行して印刷を標準エラーに復元し、標準出力に印刷できます。stderr
exec 3>&1
exec 4>&2
exec 2>&4
exec 1>&3
対話的に使用するには、コマンドごとに標準出力と標準エラーストリームをリダイレクトすることをお勧めします。>> outfile 2>&1 command with arguments