データベースをバックアップするスクリプトを書いています。次の行があります。
mysqldump --user=$dbuser --password=$dbpswd \
--Host=$Host $mysqldb | gzip > $filename
Stderrを変数に割り当てて、何か問題が発生した場合に何が起こったのかを知らせるメールを自分に送信するようにします。 stderrをstdoutにリダイレクトするソリューションを見つけましたが、stdoutが(gzipを介して)ファイルにすでに送信されているため、それを行うことはできません。変数$ resultにstderrを個別に格納するにはどうすればよいですか?
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
が含まれます。
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
それを分解し、外部から読んで、それを:
別のファイル番号(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コマンドの出力とは無関係です)。
編集:mysqldump
ではなくgzip
コマンドからstderrをリダイレクトするようにコマンドを更新しました。最初の答えは速すぎました。
dd
は、stdoutと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`