stdoutとstderrの両方をBashでファイルにリダイレクトして追加する方法は?


1533

stdoutをBashの切り捨てられたファイルにリダイレクトするには、次のように使用します。

cmd > file.txt

Bashでstdoutをリダイレクトしてファイルに追加するには、次のように使用します。

cmd >> file.txt

stdoutstderrの両方を切り捨てられたファイルにリダイレクトするには、次のように使用します。

cmd &> file.txt

stdoutstderrの両方をファイルに追加してリダイレクトするにはどうすればよいですか?cmd &>> file.txt私にとってはうまくいきませんでした。


37
&> outfileはBash(およびその他)固有のコードであり、移植性がないことに注意してください。移植性を
高める

回答:


1999
cmd >>file.txt 2>&1

Bashは次のように左から右へのリダイレクトを実行します。

  1. >>file.txtfile.txt追加モードで開き、stdoutそこにリダイレクトします。
  2. 2>&1現在どこに行きますstderr」にstdoutリダイレクトします。この場合、それは追加モードで開かれたファイルです。つまり、は現在使用し&1stdoutいるファイル記述子を再利用します。

33
よく働く!しかし、これを理解する方法はありますか、これをアトミックbash構成要素のように扱う必要がありますか?
flybywire 2009年

181
これは単純なリダイレクトです。リダイレクトステートメントは、いつものように、左から右に評価されます。>>ファイル:赤。STDOUT to file(append mode)(short for 1 >> file)2>&1:赤。STDERRから「stdoutの移動先」への解釈「STDERRをSTDOUTにリダイレクト」の解釈は間違っていることに注意してください。
TheBonsai 2009年

31
「出力(stdout、ファイル記述子1)をfile.txtに追加し、stderr(ファイル記述子2)をfdと同じ場所に送信する」と書かれています。
追って通知があるまで一時停止。

2
@TheBonsaiしかし、STDERRを別のファイルにリダイレクトして追加する必要がある場合はどうなりますか?これは可能ですか?
arod

41
あなたがそうcmd >>file1 2>>file2するなら、それはあなたが望むものを達成するはずです。
Woodrow Douglass 2013

367

Bashのバージョンに応じて、これを行うには2つの方法があります。

クラシックでポータブルな(Bash pre-4)方法は次のとおりです。

cmd >> outfile 2>&1

Bash 4以降の移植性のない方法は

cmd &>> outfile

(にアナログ&> outfile

良いコーディングスタイルを得るには、

  • 移植性が問題であるかどうかを決定します(その後、従来の方法を使用します)
  • Bash pre-4への移植性が問題になるかどうかを決定します(その後、クラシックな方法を使用します)
  • 使用する構文に関係なく、同じスクリプト内で変更しないでください(混乱!)

スクリプトが既に#!/bin/sh(意図されているかどうかに関係なく)で始まっている場合、Bash 4ソリューション、および一般的にはBash固有のコードでは対応できません。

また、Bash 4 &>>は単に短い構文であることも覚えておいてください。新しい機能などは導入されていません。

構文は(他のリダイレクト構文と並んで)ここで説明されています:http : //bash-hackers.org/wiki/doku.php/syntax/redirection#appending_redirected_output_and_error_output


8
&>>および>>と一貫性があるため、私は&>>を好みます。また、「出力にエラーを送信してこのファイルに出力を追加する」よりも、「出力とエラーをこのファイルに追加する」の方が簡単です。Linuxは、一般的にはbashの現在のバージョンを持っていながら、注意、OS Xは、執筆時点では、まだ手動でインストールを経由しての自作などにbashの4が必要です
mikemaccana

短いので1行あたりの位置がtweoiだけなので、私はもっと好きです。たとえば、zshは "&>>"から何を作りますか?
Phillipp

また、cronジョブでは、あなたのシステムがバッシュ4を持っている場合でも、事前に4の構文を使用する必要があること、注意することが重要
hyperknot

5
@zsero cronはbashをまったく使用しません...を使用しshます。ファイルの先頭に追加SHELL=/bin/bashすることで、デフォルトのシェルを変更できcrontab -eます。
Ray Foss

89

Bashでは、別のファイルへのリダイレクトを明示的に指定することもできます。

cmd >log.out 2>log_error.out

追加は次のようになります:

cmd >>log.out 2>>log_error.out

6
最初のオプションを使用して2つのストリームを同じファイルにリダイレクトすると、最初のストリームが2番目のストリームの「上」に書き込まれ、コンテンツの一部またはすべてが上書きされます。代わりにcmd >> log.out 2> log.outを使用してください。
Orestis P.

3
それをキャッチしてくれてありがとう。あなたが正しい、一方はもう一方を壊します。ただし、コマンドも機能しません。同じファイルに書き込む唯一の方法は、以前に与えられた方法だと思いますcmd >log.out 2>&1。最初の例を削除するために回答を編集しています。
アーロンR.

65

Bash 4(およびZSH 4.3.11)では:

cmd &>>outfile

箱から出してすぐ


2
@all:これはbashで機能し、簡潔であるため、良い答えです。そのため、bashが明示的に言及されていることを確認するように編集しました。
mikemaccana 2013年

10
@mikemaccana:TheBonsaiの答えは、2009年以降のbash 4ソリューションを示しています
jfs '27

52

これはうまくいくはずです:

your_command 2>&1 | tee -a file.txt

すべてのログをfile.txtに保存し、ターミナルにダンプします。


これもターミナルで出力を見たい場合の正解です。しかし、これは最初に尋ねられた質問ではありませんでした。
ミッコランタライネン

25

これを試して

You_command 1>output.log  2>&1

&> x.fileの使用はbash4で機能します。そのために残念 : (

ここにいくつかの追加のヒントがあります。

0、1、2 ... 9はbashのファイル記述子です。

0はstdin、1はstdout、2はを表しstderrorます。3〜9は他の一時的な使用のための予備です。

演算子>または>>(追加)を使用して、ファイル記述子を他のファイル記述子またはファイルにリダイレクトできます。

使用方法:< file_descriptor > > < ファイル名 | &file_descriptor >

http://www.tldp.org/LDP/abs/html/io-redirection.htmlを参照してください


あなたの例はOPが要求したものとは異なる何かをします:それはstderr You_commandをstdoutにリダイレクトし、stdoutをYou_commandfileにリダイレクトしますoutput.log。さらに、ファイルに追加されませんが、上書きされます。
pabouk 2014年

正しい例:ファイル記述子は、他のすべてのファイルで3を超える任意の値にすることができます。
イタチ2014

5
あなたの答えは、最も一般的な出力リダイレクトエラーを示します。STDERRを現在STDOUTが指している場所にリダイレクトし、その後にSTDOUTをファイルにリダイレクトした後のみです。これにより、STDERRが同じファイルにリダイレクトされることはありません。リダイレクトの順序は重要です。
Jan Wikholm、2015

1
つまり、最初にSTDERRORをSTDOUTにリダイレクトし、次にSTDOUTをファイルにリダイレクトする必要があります。 1 > output.log 2>&1
Quintus.Zhou

1
@ Quintus.Zhou Yup あなたのバージョンはerrをoutにリダイレクトし、同時にファイルにoutします。
Alex Yaroshevich 2015年

11

ほぼ10年間で、このアプローチをまだ誰も投稿していないことに驚いています。

&>>利用できない古いバージョンのbashを使用している場合は、次のこともできます。

(cmd 2>&1) >> file.txt

これはサブシェルを生成するので、の従来のアプローチよりも効率が悪く、cmd >> file.txt 2>&1その結果、現在のシェル(たとえばcdpushd)を変更する必要があるコマンドでは機能しませんが、このアプローチはより自然で理解しやすく感じられます。

  1. stderrをstdoutにリダイレクトします。
  2. ファイルに追加して、新しいstdoutをリダイレクトします。

また、括弧を使用すると、特にstdoutとstderrを別のコマンドにパイプしたい場合に、順序のあいまいさがなくなります。


この実装により、システムを実行するための1つの追加プロセスが発生します。構文の使用cmd >> file 2>&1はすべてのシェルで機能し、実行に追加のプロセスは必要ありません。
Mikko Rantalainen

@MikkoRantalainenすでに説明したように、サブシェルが生成され、効率が低下します。このアプローチの要点は、効率が大したことではない(そしてそれがめったにない)場合、この方法は覚えやすく、誤解しにくいということです。
jamesdlin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.