64

データベースをバックアップするスクリプトを書いています。次の行があります。

mysqldump --user=$dbuser --password=$dbpswd  \
   --host=$host $mysqldb | gzip > $filename

stderr を変数に割り当てて、何か問題が発生した場合に何が起こったのかを知らせる電子メールを自分に送信するようにします。stderr を stdout にリダイレクトする解決策を見つけましたが、stdout が既に (gzip 経由で) ファイルに送信されているため、それを行うことはできません。stderr を変数 $result に個別に保存するにはどうすればよいですか?

4

4 に答える 4

102

stderr を stdout にリダイレクトし、$()それをキャプチャするために使用してみてください。言い換えると:

VAR=$((your-command-including-redirect) 2>&1)

コマンドは stdout をどこかにリダイレクトするため、stderr に干渉するべきではありません。それを書くためのよりクリーンな方法があるかもしれませんが、それはうまくいくはずです。

編集:

これは本当にうまくいきます。私はそれをテストしました:

#!/bin/bash                                                                                                                                                                         
BLAH=$((
(
echo out >&1
echo err >&2
) 1>log
) 2>&1)

echo "BLAH=$BLAH"

が印刷BLAH=errされ、ファイルlogにはout.

于 2010-06-28T06:19:46.280 に答える
22

Bashの一般的なコマンドの場合、次のように実行できます。

{ error=$(command 2>&1 1>&$out); } {out}>&1

通常の出力が正常に表示され、stderrへのすべてが$ errorにキャプチャされます(改行を保持するために使用する場合は、「$ error」として引用してください)。stdoutをファイルにキャプチャするには、最後にリダイレクトを追加します。次に例を示します。

{ error=$(ls /etc/passwd /etc/bad 2>&1 1>&$out); } {out}>&1 >output

それを分解し、外側から読んで、それ:

  • ブロック全体のファイル記述$outを作成し、stdoutを複製します
  • コマンド全体のstdoutを$errorでキャプチャします(ただし、以下を参照)
  • コマンド自体がstderrをstdout(上でキャプチャされます)にリダイレクトし、次にstdoutをブロックの外側から元のstdoutにリダイレクトするため、stderrのみがキャプチャされます
于 2011-06-11T19:07:09.573 に答える
5

別のファイル番号 (たとえば 3) にリダイレクトされる前の stdout 参照を保存し、stderr をそれにリダイレクトできます。

result=$(mysqldump --user=$dbuser --password=$dbpswd  \
   --host=$host $mysqldb 3>&1 2>&3 | gzip > $filename)

したがって3>&1、ファイル番号 3 を stdout にリダイレクトします (これは stdout がパイプでリダイレクトされる前であることに注意してください)。次に2>&3、stderr をファイル番号 3 にリダイレクトします。これは現在 stdout と同じです。最後に、stdout はパイプに送られることによってリダイレクトされますが、これはファイル番号 2 と 3 には影響しません (gzip からの stdout のリダイレクトは、mysqldump コマンドからの出力とは無関係であることに注意してください)。

編集:コマンドを更新して、コマンドからstderrをリダイレクトするのmysqldumpではなくgzip、最初の回答が速すぎました。

于 2010-06-28T06:25:17.287 に答える
0

ddstdout と stderr の両方を書き込みます。

$ dd if=/dev/zero count=50 > /dev/null 
50+0 records in
50+0 records out

2 つのストリームは独立しており、個別にリダイレクト可能です。

$ dd if=/dev/zero count=50 2> countfile | wc -c
25600
$ cat countfile 
50+0 records in
50+0 records out
$ mail -s "countfile for you" thornate < countfile

本当に変数が必要な場合:

$ variable=`cat countfile`
于 2010-06-28T06:22:07.897 に答える