0

標準エラーを標準出力に送信するコマンドを取得するのに問題があります。cronに入れるつもりですが、今のところ手動で実行しています。

/home/backups/backup_scripts/backup.sh 2>&1 >> /var/log/backups/backup.log

ログファイルに標準出力に出力されたメッセージが含まれることを期待していましたが、ログファイルには標準出力しか表示されず、コンソール出力にエラーが表示されました。

私はここで何が間違っているのですか?

4

2 に答える 2

2

リダイレクトの順序が重要です。次のように変更する必要があります。

/home/backups/backup_scripts/backup.sh >> /var/log/backups/backup.log 2>&1 

これにより、stdoutがにリダイレクトされ/var/log/backups/backup.log、次にstderrがstdout(ファイルに入る)にリダイレクトされます。

次の短い形式を使用することもできます。

/home/backups/backup_scripts/backup.sh &>> /var/log/backups/backup.log

&>>file意味的には同等です>>file 2>&1

于 2012-10-01T15:07:12.640 に答える
2

これは、リダイレクトの順序が原因で発生しました。これは、「標準エラーを標準出力の現在の場所に2>&1リダイレクトする」ことを意味します。これらは左から右に処理されるため、最初の標準エラーは現在の標準出力(まだターミナル)にリダイレクトされ、次に標準出力はファイルにリダイレクトされます。読む順番を入れ替えたら

/home/backups/backup_scripts/backup.sh >> /var/log/backups/backup.log 2>&1

それはあなたが望むことをするはずです。シェルがbashの場合、標準出力と標準エラーを同時にリダイレクトするショートカットがあります。両方をcommand &> fileファイルにリダイレクトし、両方をファイルにcommand &>> file追加します。この順序の依存関係は、bashマニュアルにも記載されています

リダイレクトの順序が重要であることに注意してください。たとえば、コマンド

ls > dirlist 2>&1

コマンドがコマンドを実行している間、標準出力と標準エラーの両方をファイルdirlistに送信します。

ls 2>&1 > dirlist

標準出力がdirlistにリダイレクトされる前に、標準エラーが標準出力から複製されたため、標準出力のみをファイルdirlistに転送します。

ファイル記述子とリダイレクトがどのように機能するかについて、いくつかの誤解があると思います。カーネルには、ファイルオフセット、ステータスフラグ、およびファイル自体の名前を含む、システム上で開いているすべてのファイルの大きなテーブルがあります。次に、各プロセスには、ファイル記述子番号をこのグローバルテーブルのエントリにマップするテーブルがあります。

リダイレクトが発生する前は、グローバルテーブルは次のようになります。

A: TERMINAL

プロセステーブルは次のようになります

0: A
1: A
2: A

記述子番号0、1、および2は、それぞれstdin、stdout、およびstderrであるためです。

次に、2>&1リダイレクトが処理されます。これにより、プロセステーブルが変更され、2に1と同じグローバルエントリへのポイントが含まれるようになります。ただし、これらはすでに同じであるため、何も起こりません。

>> /var/log/backups/backup.logリダイレクションが処理されるとき。まず、ファイルが開かれ、プロセステーブルのファイル記述子3に割り当てられるため、テーブルは次のようになります。

A: TERMINAL
B: /var/log/backups/backup.log

0: A
1: A
2: A
3: B

次に、(行われたかのように)新しく開かれたファイルを指すように標準出力が変更される1>&3ため、プロセステーブルは次のようになります。

0: A
1: B
2: A
3: B

2(stderr)はまだターミナルを指していることに注意してください。

リダイレクトが他の順序で行われる場合、後のテーブル>> /var/log/backups/backup.logは同じように見えます。

0: A
1: B
2: A
3: B

そして、2>&1リダイレクションは、2ポイントを与えることを変更します

0: A
1: B
2: B
3: B

したがって、stdoutとstderrの両方がファイルに移動します。

于 2012-10-01T15:09:51.317 に答える