Viết đầu ra lệnh trong Windows cmd vào một tệp (với một twist)


9

Vì vậy, tôi đang cố gắng để chạy foo.exe, nhưng tôi không muốn đầu ra cho thiết bị đầu cuối mà vào một tệp. Đang chạy foo.exe > foo.txt nên thực hiện điều này cho tôi, nhưng nó không phải là. Khi tôi đang chạy tệp exe, tôi nhận được đầu ra. Các exe đang làm việc tốt trong những từ khác. Tuy nhiên, khi tôi cố gắng gửi đầu ra đến một tệp, điều duy nhất tôi nhận được là:

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

Điều này chỉ có xuất hiện khi tôi cố gắng gửi nó vào một tập tin. Suy nghĩ rằng nó có thể là con đường (đó là c:\Program Files (x86)\ và v.v.) bị hiểu sai, tôi đã thử chỉ định tệp đầu ra như vậy: foo.exe > c:\test.txt, nhưng vẫn không có niềm vui.

Vì vậy, ngoài việc nói rằng nhị phân mà tôi đang cố gắng chạy được viết kém, tôi có thể làm gì để khắc phục điều này không? Hãy nhớ rằng tôi nhận được đầu ra hợp lệ khi chỉ cần chạy exe, nó sẽ không in độc đáo vào một tệp. Rõ ràng đầu ra là có, câu hỏi là nếu có một số cách để bắt nó.


Điều gì xảy ra nếu bạn di chuyển chương trình sang một thư mục đơn giản (C: \ Simple hoặc thậm chí C: \) và thử những thứ này từ đó?
Jan Doggen

Câu trả lời:


21

Bạn đã không hiển thị lệnh bạn đang sử dụng đang thất bại. Nếu bạn hiển thị nó trong câu hỏi của bạn, có thể dễ dàng hơn để tìm một giải pháp cho bạn.

Tôi hy vọng lệnh của bạn là một cái gì đó như thế này:

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

Lỗi bạn nhận được có phần là manh mối:

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

Đầu tiên:
... is not recognized as an internal or external command, operable program or batch file.

Điều này thường xảy ra khi bạn cố chuyển hướng đến một tệp bằng cách sử dụng một | Thay vì một >.

Thứ hai:
'c:/Program' ...

Khi chỉ định tên tệp (hoặc đường dẫn) có chứa khoảng trắng, bạn phải bao quanh nó trong dấu ngoặc kép ( "..." ). Điều này là do khi HĐH đang xác định tệp để chuyển hướng đến, nó sẽ ngừng tìm tên tệp khi gặp không gian không trích dẫn: "c:/Program".

Thử đi:

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



Nếu ở trên không hoạt động để nắm bắt đầu ra từ foo.exe vào tệp văn bản, sau đó có một khả năng khác ...

Nếu chương trình foo.exe đang viết đầu ra của nó cho STDERR thay vì STDOUT, đầu ra của foo.exe sẽ không bị bắt bằng cách sử dụng chuyển hướng đơn giản với một lần duy nhất >. Bạn sẽ phải làm điều đó như thế này:

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



Chỉnh sửa:

Dưới đây là một lời giải thích về chuyển hướng tập tin và 2>&1 ký hiệu.

Khi một chương trình ghi vào thiết bị đầu cuối, nó có thể ghi vào một trong hai Streams.

  1. Luồng 1 được gọi là STDOUT hoặc là Tiêu chuẩn đầu ra . Thông thường, các chương trình viết "Bình thường" đầu ra cho luồng 1.

  2. Luồng 2 được gọi là STDERR hoặc là Lỗi tiêu chuẩn . Thông thường, các chương trình viết "Lỗi" đầu ra (thông báo lỗi và cảnh báo) cho luồng 2.

Liệu một chương trình ghi một đầu ra cụ thể vào STDOUT hoặc là STDERR được xác định bởi các lập trình viên và cách họ viết chương trình. Một số chương trình được viết để gửi tất cả đầu ra (đầu ra bình thường và lỗi) tới STDOUT.

Khi một chương trình được chạy mà không có chuyển hướng đầu ra, tất cả đầu ra bình thường và lỗi được gửi đến màn hình đầu cuối mà không có sự phân biệt giữa những gì STDOUT đầu ra hoặc STDERR đầu ra.

Khi bạn thực hiện chuyển hướng "bình thường" với một lần duy nhất > như thế này:

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

bạn không chỉ định Suối đang được chuyển hướng đến tệp, vì vậy Luồng 1 được giả sử.

Nó giống như khi bạn gõ nó như thế này:

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

Điều này nói với trình thông dịch lệnh ( cmd.exe ) để nắm bắt đầu ra chương trình cho STDOUT (Luồng 1) đến tên tệp được chỉ định. Các 1 trong 1> đề cập đến Luồng 1.

Trong trường hợp này, tất cả chương trình bình thường được ghi vào tệp, nhưng nếu chương trình ghi vào STDERR (Luồng 2), đầu ra đó sẽ không được ghi lại và sẽ được hiển thị trên màn hình. Đây thường là cách "mong muốn" để thực hiện để trong khi bạn chụp đầu ra chương trình bình thường, bạn có thể thấy trên màn hình nếu xảy ra lỗi.

Nếu bạn muốn chụp đầu ra "Bình thường" cho một tệp và đầu ra "Lỗi" sang một tệp khác, bạn có thể thực hiện như sau:

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

Nếu bạn muốn đầu ra "Bình thường" và đầu ra "Lỗi" được ghi lại vào tương tự tập tin, bạn có thể chỉ định nó như thế này:

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

Về cơ bản, đây là một cách "tốc ký" để chỉ định nó và nó có nghĩa là chuyển hướng Luồng 1 sang tệp đã chỉ định và cũng chuyển hướng Luồng 2 về cùng "địa điểm" (tệp) dưới dạng Luồng 1.


Chỉnh sửa:

Pacerier hỏi:

Có sự khác biệt nào giữa foo.exe & gt; "c: \ output.txt" 2 & gt; & amp; 1 và foo.exe & gt; "c: \ output.txt" 2 & gt; "c: \ output.txt"? Chúng giống hệt nhau phải không?

Câu trả lời ngắn: Bạn sẽ nghĩ chúng giống hệt nhau, nhưng không. Họ khác nhau.

Với chuyển hướng sử dụng >"filename.ext", 1>"filename.ext", hoặc là 2>"filename.ext", các > làm cho đầu ra được ghi vào Mới tập tin có tên "filename.ext". Nếu tệp "filename.ext" đã tồn tại, nó sẽ bị xóa đầu tiên.

Vì vậy, sử dụng:

foo.exe & gt; "c: \ output.txt" 2 & gt; "c: \ output.txt"

gây ra một "xung đột" trong đó cả hai chuyển hướng đang cố ghi vào cùng một tệp và cả hai đều cố xóa tệp nếu nó đã tồn tại. Điều này có thể sẽ gây ra hành vi không mong muốn. Nói chung, một hoặc một, hoặc cả hai, của đầu ra sẽ KHÔNG được ghi lại đầy đủ, hoặc có thể dự đoán được.

Kết quả thực tế sẽ phụ thuộc vào hệ điều hành và phiên bản, và cũng có thể phụ thuộc vào lệnh được thực thi. Điều có thể sẽ xảy ra là:

1 Đầu ra được gửi đến một trong các chuyển hướng sẽ bị bắt hoặc bị bắt một phần và đầu ra được gửi đến chuyển hướng khác sẽ bị mất.   2 Hệ điều hành sẽ phàn nàn về lệnh và cả hai đầu ra sẽ không bị bắt (hoàn toàn).   3 Không xác định, không mong muốn, không thể đoán trước, hành vi bất ngờ.

Trên Windows 7 và có khả năng trên Windows Vista / 8/10 và có thể trên Windows XP, hệ điều hành sẽ phàn nàn về lệnh và lệnh sẽ bị hủy.

Ví dụ: (Windows 7): Tôi có một thư mục có tên: "C:\Temp\emptyfolder" và một tệp có tên "nonexistantfile" không tồn tại ở đó.

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>

Trong trường hợp này, sử dụng một chuyển hướng ( >output.txt ), đầu ra của dir lệnh được bắt giữ các tập tin: output.txtvà thông báo lỗi File Not Found được hiển thị trên màn hình ... đây là hành vi dự kiến.

Bây giờ, sử dụng cả hai chuyển hướng ("& gt; tệp" VÀ "2 & gt; tệp"):

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>

Trong trường hợp này, hệ điều hành đã phàn nàn rằng tệp (đầu ra) đã được sử dụng. Và tệp "output.txt" kết thúc trống (0 byte) và đầu ra cho cả hai chuyển hướng đã bị mất.

Bây giờ, cuối cùng, sử dụng cả hai chuyển hướng ("& gt; tệp" VÀ "2 & gt; & amp; 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>

Trong trường hợp này, "& gt; tệp" khiến đầu ra cho "luồng 1" ("đầu ra tiêu chuẩn") bị bắt vào tệp. Và "2 & gt; & amp; 1" khiến đầu ra cho "luồng 2" ("đầu ra lỗi") được gửi qua "luồng 1" đã được chuyển hướng và cũng được ghi vào tệp (cùng).

Cũng cần lưu ý rằng thứ tự là quan trọng. Đảo ngược thứ tự như thế này:

dir nonexistant 2>&1 >output.txt

không giống nhau và có thể sẽ không cho bạn kết quả mong muốn.

Trong trường hợp này, "2 & gt; & amp; 1", được nhìn thấy và đặt trước trước, khiến đầu ra cho "luồng 2" ("đầu ra lỗi") được chuyển hướng đến nơi "luồng 1" hiện đang được chuyển đến tại thời điểm đó, là (theo mặc định), màn hình. Và "& gt; tệp" làm cho đầu ra cho "luồng 1" ("đầu ra tiêu chuẩn") bị bắt vào tệp. Kết quả cuối cùng là đầu ra của lệnh ("luồng 1") sẽ được ghi vào tệp, nhưng đầu ra lỗi ("luồng 2"), vẫn sẽ đi đến màn hình (không phải vào tệp).


Hóa ra foo.exe>"c:\test.txt" thực sự đã làm việc, nhưng nó đã gây ra lỗi khi chương trình bị lỗi (mặc dù đầu ra vẫn còn đó). Tuy nhiên, đề xuất của bạn làm cho nó thậm chí còn tốt hơn như 2>&1 làm cho khiếu nại tai nạn biến mất. Quan tâm đến chi tiết những gì nó làm? Cảm ơn một lần nữa cho một câu trả lời tuyệt vời.
pzkpfw

@ bigbadonk420 - Tôi đã cập nhật câu trả lời của mình để bao gồm thông tin về việc sử dụng 2>&1. Nếu bạn kiểm tra tệp của mình "c: \ test.txt", rất có thể bạn sẽ thấy rằng "khiếu nại sự cố" đã được ghi vào tập tin. 2>&1 không nên gây ra hoặc ngăn chương trình bị sập, nó chỉ khiến các thông báo lỗi bị bắt chứ không hiển thị.
Kevin Fegan

1
Vâng, vì một số lý do nó làm.
pzkpfw

1
@ bigbadonk420 - 'for some reason it does' theo cách nào nó bị ảnh hưởng bởi chuyển hướng? Bạn đang nói rằng khi bạn chuyển hướng bao gồm 2>&1, rằng lỗi không xảy ra? Bạn thấy thông báo lỗi gì khi xảy ra lỗi?
Kevin Fegan

1
Khi nào 2>&1 không được bao gồm, chương trình gặp sự cố và tôi nhận được hộp thoại "chương trình này đã ngừng đáp ứng" của Windows. Khi tôi bao gồm nó, nó không. Không biết tại sao. Đầu ra được tạo ra trong cả hai trường hợp mặc dù.
pzkpfw
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.