一度に多くのコマンドをリダイレクトするソリューションについて:
#!/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 |
少なくとも少し便利です。