すべての出力を1つのファイル、デバッグログ、およびターミナルにリダイレクトする必要があるbashファイルがあります。 stdoutとstderrの両方をデバッグにリダイレクトし、スクリプト内のすべてのコマンドについてログに記録する必要があります。
2>&1を追加したくない| tee -a $ DEBUG
ファイル内のすべてのコマンドに対して。私はと一緒に暮らすことができました| tee -a $ DEBUG
。
exec 2>&1
のようなものでそれを行う方法があったことを覚えています 。
現在、次のようなものを使用しています:
#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG
しかし、それは機能しません。誰かが解決策を持っていますか/原因を説明できますか?
承認された回答:
一度に多くのコマンドをリダイレクトするソリューションについて:
#!/bin/bash
{
somecommand
somecommand2
somecommand3
} 2>&1 | tee -a $DEBUGLOG
元のソリューションが機能しない理由:exec 2>&1は、標準エラー出力をシェルの標準出力にリダイレクトします。シェルの標準出力は、コンソールからスクリプトを実行すると、コンソールになります。コマンドのパイプリダイレクトは、コマンドの標準出力のみをリダイレクトします。
somecommand
の観点から 、その標準出力は tee
に接続されたパイプに入ります 標準エラーは、シェルの標準エラーと同じファイル/疑似ファイルに入ります。これは、シェルの標準出力にリダイレクトされます。これは、コンソールからプログラムを実行するとコンソールになります。
それを説明する1つの本当の方法は、実際に何が起こっているかを確認することです。
ターミナルから実行すると、シェルの元の環境は次のようになります。
stdin -> /dev/pts/42
stdout -> /dev/pts/42
stderr -> /dev/pts/42
標準エラーを標準出力にリダイレクトした後( exec 2>&1
)、あなたは…基本的に何も変更しません。ただし、スクリプトの標準出力をファイルにリダイレクトすると、次のような環境になります。
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /dev/pts/42
次に、シェルの標準エラーを標準出力にリダイレクトすると、次のようになります:
stdin -> /dev/pts/42
stdout -> /your/file
stderr -> /your/file
コマンドを実行すると、この環境が継承されます。コマンドを実行してそれをteeにパイプすると、コマンドの環境は次のようになります:
stdin -> /dev/pts/42
stdout -> pipe:[4242]
stderr -> /your/file
したがって、コマンドの標準エラーは、シェルが標準エラーとして使用するものに引き続き適用されます。
関連:$ {!FOO}とzsh?
/ proc / [pid] / fd
を見ると、実際にコマンドの環境を確認できます。 : ls -l
を使用します シンボリックリンクのコンテンツも一覧表示します。 コード> ここのファイルは標準入力、
1
標準出力であり、 2
標準エラーです。コマンドがさらに多くのファイルを開くと(そしてほとんどのプログラムが開きます)、それらも表示されます。プログラムは、標準の入出力をリダイレクトまたはクローズして、を再利用することもできます。 、
1
および2
。