題 將Windows cmd中的命令輸出寫入文件(帶有扭曲)


所以我想跑 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時,我確實得到了有效的輸出,它只是不能很好地打印到文件。顯然輸出是存在的,問題是是否有某種方法可以捕獲它。


8
2018-05-02 12:44


起源


如果將程序移動到一個簡單的目錄(C:\ Simple或甚至C:\)並從那裡嘗試這些東西會發生什麼? - Jan Doggen


答案:


您尚未顯示正在使用的命令失敗。如果您在問題中顯示,可能更容易找到適合您的解決方案。

我希望你的命令是這樣的:

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.

當您嘗試使用a重定向到文件時,通常會發生這種情況 | 代替 >

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

指定包含空格的文件名(或路徑)時,必須用雙引號括起來("...")。這是因為當操作系統確定要重定向到的文件時,它會在遇到未加引號的空格時停止查找文件名: "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 符號。

當程序寫入終端時,它可以寫入兩個中的一個 Streams

  1. 流1被稱為 STDOUT 要么 標準輸出。通常,程序會編寫它們的 “正常” 輸出到流1。

  2. 流2被稱為 STDERR 要么 標準錯誤。通常,程序會編寫它們的 “錯誤” 輸出(錯誤和警告消息)到流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 在 1> 指的是第1流。

在這種情況下,所有正常程序都被捕獲到文件中,但如果程序寫入 STDERR (流2),該輸出將不被捕獲並將顯示在屏幕上。這通常是“理想的”方式,這樣當您捕獲正常的程序輸出時,您可以在屏幕上看到是否發生錯誤。

如果要將“正常”輸出捕獲到一個文件,並將“錯誤”輸出到另一個文件,可以這樣做:

    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

這基本上是一種指定它的“速記”方式,它意味著將Stream 1重定向到指定文件,並將Stream 2重定向到同一文件 “地點” (文件)作為流1。


編輯: 

Pacerier問道:

foo.exe>“c:\ output.txt”2>&1和foo.exe>“c:\ output.txt”2>“c:\ output.txt”之間有什麼區別嗎?它們是一樣的嗎?

簡短的回答:你會認為它們是相同的,但沒有。它們是不同的。

使用重定向 >"filename.ext"1>"filename.ext", 要么 2>"filename.ext"> 導致輸出寫入a  文件名為“filename.ext”。如果文件“filename.ext”已存在,則將首先刪除它。

所以,使用:

foo.exe>“c:\ output.txt”2>“c:\ output.txt”

導致“衝突”,其中兩個重定向都試圖寫入同一個文件,並且如果文件已存在,則兩者都試圖刪除該文件。這可能會導致不良行為。通常,輸出中的一個或另一個或兩個將不會被完全捕獲或可預測地捕獲。

實際結果取決於操作系統和版本,也可能取決於正在執行的命令。可能發生的事情是:

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>

在這種情況下,使用一個重定向(>output.txt),輸出 dir 命令被捕獲的文件: output.txt,以及錯誤消息 File Not Found 屏幕上顯示...這是預期的行為。

現在,使用兩個重定向(“> file”AND“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”)仍然會進入屏幕(而不是文件)。


19
2018-05-02 14:24



事實證明 foo.exe>"c:\test.txt" 實際上工作,但它拋出了程序崩潰的錯誤(輸出仍然在那裡)。但是,你的建議使它變得更好 2>&1 讓墜機投訴消失了。注意詳細說明它的作用?再次感謝您的回答。 - pzkpfw
@ bigbadonk420 - 我更新了我的答案,包括有關使用的信息 2>&1。如果你檢查你的文件“c:\ test.txt”,你很可能會看到 “崩潰投訴” 被寫入文件。 2>&1 不應該導致或阻止程序崩潰,它只會導致捕獲而不是顯示錯誤消息。 - Kevin Fegan
好吧,出於某種原因,它確實如此。 - pzkpfw
@ bigbadonk420 - 'for some reason it does' 它以何種方式受重定向影響?你是說當你重定向包括 2>&1,那個錯誤沒有發生?發生錯誤時您看到了什麼錯誤消息? - Kevin Fegan
什麼時候 2>&1 不包括,程序崩潰,我得到標準Windows“此程序已停止響應”對話框。當我包括它時,它不會。不知道為什麼。但是在兩種情況下都會生成輸出。 - pzkpfw