Windows cmdのコマンド出力をファイルに書き込む(ひねりを加えた)


9

だから私は実行しようとしfoo.exeていますが、ターミナルへの出力ではなくファイルにしたいです。ランニングfoo.exe > foo.txtは私にとってこれを達成するはずですが、そうではありません。exeファイルを実行すると、出力が表示されます。言い換えれば、exeは正常に動作しています。ただし、出力をファイルに送信しようとすると、唯一の結果は次のとおりです。

'c:/Program' is not recognized as an internal or external command,
operable program or batch file.

これは、ファイルに送信しようとしたときにのみ表示されます。c:\Program Files (x86)\誤って解釈されるパス(など)である可能性があると考えて、出力ファイルを次のように指定してみましたfoo.exe > c:\test.txt

それで、私が実行しようとしているバイナリが不十分に書かれていることを述べる以外に、これを修正するために私ができることはありますか?単にexeを実行しただけでは有効な出力が得られることに注意してください。ファイルにうまく出力されません。明らかに出力はそこにありますが、問題はそれをキャッチする方法があるかどうかです。


プログラムを単純なディレクトリ(C:\ SimpleまたはC:\にさえ)に移動し、そこからこれらのことを試みるとどうなりますか?
Jan Doggen、2013年

回答:


21

使用しているコマンドが失敗していることを示していません。質問にそれを表示すると、解決策を見つけやすくなります。

私はあなたのコマンドが次のようなものであることを期待しています:

C:\>foo.exe|c:\Program Files (x86)\something\test.txt

あなたが受け取っているエラーはやや手がかりです:

'c:/Program' is not recognized as an internal or external command, operable program or batch file.

最初:
... is not recognized as an internal or external command, operable program or batch file.

これは通常、の|代わりにを使用してファイルにリダイレクトしようとしたときに発生します>

第二:
'c:/Program' ...

スペースを含むファイル名(またはパス)を指定する場合は、二重引用符("...")で囲む必要があります。これは、リダイレクト先のファイルをOSが決定しているときに、引用符で囲まれていないスペースが見つかると、ファイル名の検索を停止するためです"c:/Program"

これを試して:

foo.exe>"c:\Program Files (x86)\something\test.txt"



上記がfoo.exeテキストファイルへの出力をキャプチャするために機能しない場合は、別の可能性があります...

プログラムfoo.exeがのSTDERR代わりにその出力を書き込んでいる場合STDOUT、の出力はfoo.exe、単一のを使用した単純なリダイレクトではキャプチャされません>。あなたはこのようにする必要があります:

foo.exe>"c:\Program Files (x86)\something\test.txt" 2>&1



編集:

ここでは、ファイルのリダイレクトと2>&1表記について説明します。

プログラムが端末に書き込むとき、2つのうちの1つに書き込むことができますStreams

  1. ストリーム1はSTDOUTまたはStandard-Outputと呼ばれます。通常、プログラムは「通常の」出力をストリーム1に書き込みます。

  2. ストリーム2は、STDERRまたはStandard-Errorと呼ばれます。通常、プログラムは「エラー」出力(エラーおよび警告メッセージ)をストリーム2に書き込みます。

プログラムは、特定の出力を書き込みするかどうかSTDOUTまたはSTDERRプログラマによって決定され、それらがどのようにプログラムを書きました。一部のプログラムは、すべての出力(通常の出力とエラー)をに送信するように作成されていますSTDOUT

プログラムはなし出力のリダイレクトを実行すると、すべての通常、エラー出力が何であるかの区別なしで端末画面に送信されるSTDOUT出力またはSTDERR出力。

次の>ような単一の「通常の」リダイレクトを行う場合:

foo.exe > "c:\Program Files (x86)\something\test.txt"

ファイルにリダイレクトされるストリームを指定していないため、ストリーム1が想定されます。

次のように入力した場合と同じです。

foo.exe 1> "c:\Program Files (x86)\something\test.txt"

これは、コマンドインタープリター(cmd.exe)に、STDOUT(ストリーム1)のプログラム出力を指定したファイル名にキャプチャするように指示します。ストリーム1を指します。11>

この場合、すべての通常のプログラムがファイルにキャプチャされますが、プログラムがSTDERR(ストリーム2)に書き込む場合、その出力はキャプチャされず、画面に表示されます。通常、これは「望ましい」方法であり、通常のプログラム出力をキャプチャしているときに、エラーが発生したかどうかを画面で確認できます。

「通常」の出力を1つのファイルにキャプチャし、「エラー」出力を別のファイルにキャプチャする場合は、次のようにします。

    foo.exe > "c:\output.txt" 2> "C:\error.txt"
or
    foo.exe 1> "c:\output.txt" 2> "C:\error.txt"

「通常」出力と「エラー」出力を同じファイルにキャプチャする場合は、次のように指定できます。

foo.exe > "c:\output.txt" 2>&1

これは基本的にそれを指定する「省略形」の方法であり、ストリーム1を指定したファイルにリダイレクトし、さらにストリーム2をストリーム1と同じ「場所」(ファイル)にリダイレクトすることを意味します。


編集:

パチェリエが尋ねた:

foo.exe> "c:\ output.txt" 2>&1とfoo.exe> "c:\ output.txt" 2> "c:\ output.txt"の間に違いはありますか?それらは同じですか?

短い答え:それらは同一であると思いますが、違います。彼らは違う。

リダイレクトが使用して>"filename.ext"1>"filename.ext"または2>"filename.ext">出力がに書き込まれ、新しい「ファイル名。拡張子」という名前のファイル。ファイル「filename.ext」がすでに存在する場合は、最初に削除されます。

したがって、使用:

foo.exe> "c:\ output.txt" 2> "c:\ output.txt"

両方のリダイレクトが同じファイルに書き込もうとし、すでに存在する場合は両方がファイルを削除しようとする「競合」を引き起こします。これにより、望ましくない動作が発生する可能性があります。一般に、出力のどちらか一方、または両方が完全に、または予測どおりにキャプチャされません。

実際の結果は、オペレーティングシステムとバージョンによって異なり、実行中のコマンドによっても異なる場合があります。起こりそうなことは:

1リダイレクトの1つに送信された出力はキャプチャされるか、部分的にキャプチャされ、他のリダイレクトに送信された出力は失われます。2オペレーティングシステムはコマンドについて文句を言い、どちらの出力も(完全に)キャプチャされません。3未定義、望ましくない、予測できない、予期しない動作。

Windows 7では、おそらくWindows Vista / 8/10、そして場合によってはWindows XPでは、オペレーティングシステムがコマンドについて文句を言い、コマンドがキャンセルされます。

例(Windows 7):という名前のフォルダーが"C:\Temp\emptyfolder"あり、「nonexistantfile」という名前のファイルがそこに存在しません。

C:\>cd "\Temp\emptyfolder"

C:\Temp\emptyfolder>dir nonexistantfile>output.txt
File Not Found

C:\Temp\emptyfolder>type output.txt
 Volume in drive F is FFFFx1tb
 Volume Serial Number is 4011-A5C6

 Directory of C:\Temp\emptyfolder

C:\Temp\emptyfolder>

この場合、1つのリダイレクト(>output.txt)を使用して、dirコマンドの出力がファイルにキャプチャされoutput.txt、エラーメッセージ File Not Foundが画面に表示されます...これは予想される動作です。

次に、両方のリダイレクト( "> file"および "2> file")を使用します。

C:\Temp\emptyfolder>dir nonexistantfile>output.txt 2>output.txt
The process cannot access the file because it is being used by another process.
C:\Temp\emptyfolder>type output.txt

C:\Temp\emptyfolder>

この場合、オペレーティングシステムは、(outout)ファイルが既に使用されていると不平を言いました。そして、ファイル「output.txt」は空(0バイト)になり、両方のリダイレクトの出力が失われました。

最後に、両方のリダイレクト( "> file" AND "2>&1")を使用します。

C:\Temp\emptyfolder>dir nonexistantfile>output.txt 2>&1

C:\Temp\emptyfolder>type output.txt
 Volume in drive C is CCCCCCCC
 Volume Serial Number is 1234-ABCD

 Directory of C:\Temp\emptyfolder

File Not Found

C:\Temp\emptyfolder>

この場合、 "> file"を指定すると、 "stream 1"( "標準出力")の出力がファイルにキャプチャされます。「2>&1」を指定すると、「ストリーム2」の出力(「エラー出力」)がすでにリダイレクトされた「ストリーム1」を介して送信され、(同じ)ファイルにもキャプチャされます。

順序が重要であることも注目に値します。このように順序を逆にする:

dir nonexistant 2>&1 >output.txt

同じではなく、おそらく望ましい結果が得られません。

この場合、「2>&1」が最初に表示され、歳差運動をします。これにより、「ストリーム2」の出力(「エラー出力」)が「ストリーム1」が現在向けられている場所にリダイレクトされます。瞬間は、(デフォルトでは)画面です。"> file"を指定すると、 "stream 1"( "標準出力")の出力がファイルにキャプチャされます。最終結果として、コマンドの出力( "ストリーム1")はファイルにキャプチャされますが、エラー出力( "ストリーム2")は画面に(ファイルではなく)送信されます。


ことが判明したがfoo.exe>"c:\test.txt"、実際に働いていたが、それはプログラムが(出力もののまだそこにあった)クラッシュしたというエラーを投げました。しかし、あなたの提案は2>&1、衝突の苦情がなくなったので、それをさらに良くしました。それが何をするかについて詳しく説明することに気をつけますか?すばらしい回答をありがとう。
pzkpfw 2013年

@ bigbadonk420-の使用に関する情報を含めるように回答を更新しました2>&1。ファイル「c:\ test.txt」を調べると、「クラッシュの苦情」がファイルに書き込まれたことがわかります。2>&1プログラムのクラッシュを引き起こしたり防止したりすべきではありません。エラーメッセージが表示されるのではなくキャプチャされるだけです。
Kevin Fegan 2013年

1
まあ、何らかの理由でそれはありません。
pzkpfw 2013年

1
@ bigbadonk420- 'for some reason it does'リダイレクトによってどのような影響を受けますか?を含めてリダイレクトする2>&1と、エラーが発生しないということですか?エラーが発生すると、どのエラーメッセージが表示されますか?
Kevin Fegan、2013年

1
2>&1が含まれていない場合、プログラムがクラッシュし、標準のWindowsの「このプログラムは応答を停止しました」ダイアログが表示されます。含める場合は含めません。なぜだかわかりません。ただし、どちらの場合も出力が生成されます。
pzkpfw 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.