一度に多くのコマンドをリダイレクトするソリューションについて:
#!/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
そのため、コマンドの標準エラーは、シェルが標準エラーとして使用するものになります。
実際にコマンドの環境を確認するには、シンボリックリンクのコンテンツを一覧表示/proc/[pid]/fdするls -lためにも使用します。0ここでのファイルは標準入力、1標準出力、および2標準エラーです。コマンドがさらにファイルを開くと(そしてほとんどのプログラムが開きます)、それらも表示されます。プログラムはまた、標準入力/出力と再利用をリダイレクトするか、終了することができます0、1と2。
|&は、のショートカットとして機能し、2>&1 |少なくとも少し便利です。