Chuyển hướng stdout Windows cmd và stderr sang một tệp duy nhất


688

Tôi đang cố gắng chuyển hướng tất cả đầu ra (stdout + stderr) của lệnh DOS sang một tệp duy nhất:

C:\>dir 1> a.txt 2> a.txt
The process cannot access the file because it is being used by another process.

Có thể, hoặc tôi chỉ nên chuyển hướng đến hai tệp riêng biệt?


14
TechNet: Sử dụng toán tử chuyển hướng lệnh (trả lời câu hỏi này tốt hơn bất kỳ câu trả lời nào ở đây).
Martin Prikryl

1
2> & 1 vì nó không thể mở lại cùng một tệp
Luke

Câu trả lời:


1090

Bạn muốn:

dir > a.txt 2>&1

Cú pháp 2>&1sẽ chuyển hướng 2(stderr) đến 1(stdout). Bạn cũng có thể ẩn tin nhắn bằng cách chuyển hướng đến NUL, giải thích thêm và ví dụ về MSDN .


32
cảm ơn vì điều này, không biết rằng cú pháp shell unix này cũng hoạt động với DOS!
chaindriver

20
điều này là tuyệt vời để ẩn tất cả đầu ra .. net stop w3svc >NUL 2>&1.. cảm ơn!
wasatchwizard

3
@wasatchwizard Ithink Tôi gặp rắc rối với điều đó, nhưng> NUL 2> NUL hoạt động tốt
FrinkTheBrave

13
Nếu có một Tay cầm, không thể có khoảng trắng giữa Tay cầm (tức là 2) và toán tử chuyển hướng (tức là>). Do đó 2> 2.txtcông trình (hoặc 2> &1) 2 > 2.txtkhông; 2 > &1không làm.
Hạt đậu đỏ

9
Tôi yêu SO rất nhiều. "Ugh, vấn đề nhỏ một lần này sẽ diễn ra trong một giờ". Tôi mất nhiều thời gian hơn để gõ bình luận này hơn là để tìm câu trả lời này.
Brandon

195

Câu trả lời của Anders Lindahl là chính xác, nhưng cần lưu ý rằng nếu bạn đang chuyển hướng thiết bị xuất chuẩn sang tệp và muốn chuyển hướng stderr thì bạn PHẢI đảm bảo rằng nó 2>&1được chỉ định SAU khi 1>chuyển hướng, nếu không nó sẽ không hoạt động.

REM *** WARNING: THIS WILL NOT REDIRECT STDERR TO STDOUT ****
dir 2>&1 > a.txt

10
SAU là điều khiến tôi mất hàng giờ để tìm ra DelboyJay có gì sai! Cảm ơn bạn!
Nam G VU

4
Có phải nó được giải thích ở bất cứ đâu tại sao đặt 2> & 1 trước 1> sẽ không đạt được hiệu quả như mong muốn? Tôi hoàn toàn nghi ngờ điều này có liên quan đến cách "cmd" phân tích các lệnh mang lại hai ý nghĩa khác nhau tùy thuộc vào thứ tự mà bạn chỉ định chuyển hướng. Nhưng các quy tắc ngữ nghĩa được ghi lại ở bất cứ đâu vì tôi cho rằng đây là thứ đáng để học vì nó có thể lãng phí hàng giờ.
igbgotiz

12
@igbgotiz 2> & 1 có nghĩa là 'chuyển hướng luồng 2 sang luồng 1'. Vì vậy, bạn cần thiết lập luồng 1 trước
FrinkTheBrave

3
@FrinkTheBrave nhưng luồng 1 là đầu ra tiêu chuẩn (ví dụ: bàn điều khiển) nếu không được chỉ định rõ ràng. Điều đó vẫn không giải thích nó imho.
MarioDS

1
@MDeSchaepmeester, nếu bạn làm thế dir 2>&1 > a.txt, trước tiên bạn chuyển hướng ( >) luồng 2 (stderr) sang luồng 1 (stdout). Sau đó, sau khi cả hai đã được kết hợp với nhau, bạn sẽ chuyển hướng thiết bị xuất chuẩn ( >không có chỉ định) vào tệp. Nếu bạn muốn stderr đi đến một nơi khác, trước tiên bạn không thể tham gia nó với thiết bị xuất chuẩn.
cp.engr

80

Thông tin cơ bản từ MSKB

Mặc dù câu trả lời được chấp nhận cho câu hỏi này là chính xác, nhưng thực sự không có gì nhiều để giải thích tại sao nó hoạt động và vì cú pháp không rõ ràng ngay lập tức nên tôi đã tìm một cách nhanh chóng để tìm hiểu điều gì đang thực sự xảy ra. Với hy vọng thông tin này hữu ích cho người khác, tôi sẽ đăng nó ở đây.

Lấy từ MS Hỗ trợ KB 110930 .


Từ MSKB110930

Chuyển hướng thông báo lỗi từ Dấu nhắc lệnh: STDERR / STDOUT

Tóm lược

Khi chuyển hướng đầu ra từ một ứng dụng bằng biểu tượng '>', thông báo lỗi vẫn in ra màn hình. Điều này là do các thông báo lỗi thường được gửi đến luồng Lỗi tiêu chuẩn thay vì luồng Tiêu chuẩn.

Đầu ra từ một ứng dụng hoặc lệnh điều khiển (Command Prompt) thường được gửi đến hai luồng riêng biệt. Đầu ra thông thường được gửi đến Standard Out (STDOUT) và các thông báo lỗi được gửi đến Lỗi tiêu chuẩn (STDERR). Khi bạn chuyển hướng đầu ra của bàn điều khiển bằng biểu tượng ">", bạn chỉ chuyển hướng STDOUT. Để chuyển hướng STDERR, bạn phải chỉ định '2>' cho biểu tượng chuyển hướng. Điều này chọn luồng đầu ra thứ hai là STDERR.

Thí dụ

Lệnh dir file.xxx( file.xxxkhông tồn tại) sẽ hiển thị đầu ra sau:

Volume in drive F is Candy Cane Volume Serial Number is 34EC-0876

File Not Found

Nếu bạn chuyển hướng đầu ra cho NULthiết bị bằng cách sử dụng dir file.xxx > nul, bạn vẫn sẽ thấy phần thông báo lỗi của đầu ra, như sau:

File Not Found

Để chuyển hướng (chỉ) thông báo lỗi đến NUL, sử dụng lệnh sau:

dir file.xxx 2> nul

Hoặc, bạn có thể chuyển hướng đầu ra đến một nơi và các lỗi đến một nơi khác.

dir file.xxx > output.msg 2> output.err

Bạn có thể in lỗi và đầu ra tiêu chuẩn thành một tệp bằng cách sử dụng lệnh "& 1" để chuyển hướng đầu ra cho STDERR sang STDOUT và sau đó gửi đầu ra từ STDOUT đến một tệp:

dir file.xxx 1> output.msg 2>&1

29

Để thêm thiết bị xuất chuẩn và thiết bị xuất chuẩn vào tệp logfile chung của tập lệnh:

dir >> a.txt 2>&1

9
Phần >>bổ sung vào tệp >ghi đè lên tệp.
delliottg

13

Đúng, xử lý tệp 1 cho quy trình là STDOUT, được chuyển hướng bởi 1>hoặc bởi >(1 có thể được bỏ qua, theo quy ước, trình thông dịch lệnh [cmd.exe] biết để xử lý điều đó). Xử lý tệp 2 là STDERR, được chuyển hướng bởi 2>.

Lưu ý rằng nếu bạn đang sử dụng những tệp này để tạo các tệp nhật ký, thì trừ khi bạn gửi ra ngoài cho các tệp nhật ký _uniquely_named_ (ví dụ: ngày và thời gian được đóng dấu), thì nếu bạn chạy cùng một quy trình hai lần, thì chuyển hướng sẽ ghi đè lên ( thay thế) tệp nhật ký trước đó.

Các >>(đối với một trong hai STDOUT hoặc thiết bị lỗi chuẩn) sẽ nối không REPLACE tập tin. Vì vậy, bạn nhận được một logfile tích lũy, hiển thị kết quả từ tất cả các lần chạy của quy trình - thường hữu ích hơn.

Những con đường mòn hạnh phúc ...


2

Tuy nhiên, không có gì đảm bảo rằng đầu ra của SDTOUTSTDERRđược đan xen từng dòng theo thứ tự kịp thời, sử dụng POSIXcú pháp hợp nhất chuyển hướng.

Nếu một ứng dụng sử dụng đầu ra được đệm, có thể xảy ra rằng văn bản của một luồng được chèn vào luồng khác ở ranh giới bộ đệm, có thể xuất hiện ở giữa một dòng văn bản.

Một logger đầu ra giao diện điều khiển chuyên dụng (Tức là "StdOut/StdErr Logger"bởi 'LoRd MuldeR') có thể đáng tin cậy hơn cho một nhiệm vụ như vậy.

Xem: Dự án nguồn mở của MuldeR


0

Trong một tệp bó (Windows 7 trở lên) tôi thấy phương pháp này đáng tin cậy nhất

Call :logging >"C:\Temp\NAME_Your_Log_File.txt" 2>&1
:logging
TITLE "Logging Commands"
ECHO "Read this output in your log file"
ECHO ..
Prompt $_
COLOR 0F

Rõ ràng, sử dụng bất kỳ lệnh nào bạn muốn và đầu ra sẽ được chuyển đến tệp văn bản. Sử dụng phương pháp này là đáng tin cậy TUY NHIÊN KHÔNG có đầu ra trên màn hình.


(về cơ bản cùng một câu trả lời được đưa ra vài lần trước đây.) Bạn có thể buộc đầu ra ra màn hình với >con echo This goes to screenCũng hữu ích cho đầu vào của người dùng >con set /p "var="Input: "Lưu ý: những dòng đó sẽ chỉ xuất hiện trên màn hình chứ không phải được chuyển hướng đến tệp.
Stephan
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.