ฉันพยายามเปลี่ยนเส้นทางเอาต์พุตทั้งหมด (stdout + stderr) ของคำสั่งDOSเป็นไฟล์เดียว:
C:\>dir 1> a.txt 2> a.txt
The process cannot access the file because it is being used by another process.
เป็นไปได้หรือฉันควรเปลี่ยนเส้นทางไปยังสองไฟล์แยกกัน
ฉันพยายามเปลี่ยนเส้นทางเอาต์พุตทั้งหมด (stdout + stderr) ของคำสั่งDOSเป็นไฟล์เดียว:
C:\>dir 1> a.txt 2> a.txt
The process cannot access the file because it is being used by another process.
เป็นไปได้หรือฉันควรเปลี่ยนเส้นทางไปยังสองไฟล์แยกกัน
คำตอบ:
คุณต้องการ:
dir > a.txt 2>&1
ไวยากรณ์2>&1
จะเปลี่ยนเส้นทาง2
(stderr) ไปยัง1
(stdout) นอกจากนี้คุณยังสามารถซ่อนข้อความโดยการเปลี่ยนเส้นทางไปNUL
, คำอธิบายเพิ่มเติมและตัวอย่างใน MSDN
net stop w3svc >NUL 2>&1
.. ขอบคุณ!
2> 2.txt
งาน (หรือ2> &1
) 2 > 2.txt
ไม่; 2 > &1
ไม่.
คำตอบของ Anders Lindahl นั้นถูกต้อง แต่ควรสังเกตว่าหากคุณเปลี่ยนเส้นทาง stdout ไปยังไฟล์และต้องการเปลี่ยนเส้นทาง stderr ด้วยเช่นกันคุณต้องแน่ใจว่า2>&1
ได้ระบุไว้หลังการ1>
เปลี่ยนเส้นทางมิฉะนั้นจะไม่ทำงาน
REM *** WARNING: THIS WILL NOT REDIRECT STDERR TO STDOUT ****
dir 2>&1 > a.txt
dir 2>&1 > a.txt
เป็นคนแรกคุณจะเปลี่ยนเส้นทาง ( >
) สตรีม 2 (stderr) เพื่อสตรีม 1 (stdout) จากนั้นหลังจากที่ทั้งคู่เข้าร่วมกันแล้วคุณจะเปลี่ยนเส้นทาง stdout ( >
โดยไม่มีตัวระบุ) ไปยังไฟล์ หากคุณต้องการให้ stderr ไปที่อื่นคุณจะไม่สามารถเข้าร่วมกับ stdout ก่อนได้
ในขณะที่คำตอบที่ได้รับการยอมรับสำหรับคำถามนี้ถูกต้อง แต่ก็ไม่ได้อธิบายอะไรมากนักว่าทำไมมันถึงทำงานได้จริงและเนื่องจากไวยากรณ์ไม่ชัดเจนในทันทีฉันจึงทำ google แบบด่วนเพื่อค้นหาว่าเกิดอะไรขึ้นจริง ด้วยความหวังว่าข้อมูลนี้จะเป็นประโยชน์ต่อผู้อื่นฉันโพสต์ไว้ที่นี่
ที่นำมาจากMS สนับสนุน KB 110930
การเปลี่ยนเส้นทางข้อความแสดงข้อผิดพลาดจากพรอมต์คำสั่ง: STDERR / STDOUT
สรุป
เมื่อเปลี่ยนเส้นทางเอาต์พุตจากแอปพลิเคชันโดยใช้สัญลักษณ์ '>' ข้อความแสดงข้อผิดพลาดจะยังคงพิมพ์ไปที่หน้าจอ นี่เป็นเพราะข้อความข้อผิดพลาดมักจะถูกส่งไปยังกระแสข้อผิดพลาดมาตรฐานแทนกระแสออกมาตรฐาน
เอาต์พุตจากแอ็พพลิเคชันหรือคำสั่งคอนโซล (Command Prompt) มักถูกส่งไปยังสตรีมแยกกันสองรายการ เอาต์พุตปกติถูกส่งไปที่ Standard Out (STDOUT) และข้อความผิดพลาดจะถูกส่งไปที่ Standard Error (STDERR) เมื่อคุณเปลี่ยนเส้นทางคอนโซลเอาต์พุตโดยใช้สัญลักษณ์ ">" คุณจะเปลี่ยนเส้นทาง STDOUT เท่านั้น ในการเปลี่ยนเส้นทาง STDERR คุณต้องระบุ '2>' สำหรับสัญลักษณ์การเปลี่ยนเส้นทาง นี่เป็นการเลือกเอาต์พุตสตรีมที่สองซึ่งคือ STDERR
ตัวอย่าง
คำสั่ง
dir file.xxx
(ที่file.xxx
ไม่มีอยู่) จะแสดงผลลัพธ์ต่อไปนี้:Volume in drive F is Candy Cane Volume Serial Number is 34EC-0876 File Not Found
หากคุณเปลี่ยนเส้นทางผลลัพธ์ไปยัง
NUL
อุปกรณ์ที่ใช้dir file.xxx > nul
คุณจะยังคงเห็นข้อความแสดงข้อผิดพลาดส่วนหนึ่งของผลลัพธ์เช่นนี้:File Not Found
หากต้องการเปลี่ยนเส้นทาง (เฉพาะ) ข้อความแสดงข้อผิดพลาดไปยังให้
NUL
ใช้คำสั่งต่อไปนี้:dir file.xxx 2> nul
หรือคุณสามารถเปลี่ยนเส้นทางผลลัพธ์ไปยังที่เดียวและข้อผิดพลาดไปที่อื่น
dir file.xxx > output.msg 2> output.err
คุณสามารถพิมพ์ข้อผิดพลาดและเอาต์พุตมาตรฐานไปยังไฟล์เดียวโดยใช้คำสั่ง "& 1" เพื่อเปลี่ยนทิศทางเอาต์พุตสำหรับ STDERR ไปยัง STDOUT แล้วส่งเอาต์พุตจาก STDOUT ไปยังไฟล์:
dir file.xxx 1> output.msg 2>&1
ในการเพิ่ม stdout และ stderr ให้กับล็อกไฟล์ทั่วไปของสคริปต์:
dir >> a.txt 2>&1
>>
ผนวกไปยังไฟล์ที่>
เขียนทับไฟล์
ถูกต้องจัดการไฟล์ 1 สำหรับกระบวนการคือ STDOUT เปลี่ยนเส้นทางโดย1>
หรือ>
(1 สามารถละเว้นโดยการประชุมคำสั่งล่าม [cmd.exe] รู้ว่าจะจัดการกับมัน) จับไฟล์ที่ 2 คือ STDERR, 2>
เปลี่ยนเส้นทาง
โปรดทราบว่าหากคุณกำลังใช้สิ่งเหล่านี้เพื่อสร้างไฟล์บันทึกนอกจากว่าคุณกำลังส่ง outut ไปที่ _uniquely_named_ (เช่นไฟล์บันทึกวันที่และเวลาประทับ) จากนั้นหากคุณเรียกใช้กระบวนการเดียวกันสองครั้งการเปลี่ยนเส้นทางจะเขียนทับ ( แทนที่) ไฟล์บันทึกก่อนหน้า
>>
(อย่างใดอย่างหนึ่งหรือ STDOUT STDERR) จะผนวกไม่แทนที่ไฟล์ ดังนั้นคุณจะได้รับล็อกไฟล์สะสมแสดงผลจากการดำเนินการทั้งหมด - โดยทั่วไปมีประโยชน์มากกว่า
เส้นทางที่มีความสุข ...
อย่างไรก็ตามมีไม่รับประกันว่าผลลัพธ์ของSDTOUT
และSTDERR
มีการผสมผสานระหว่างบรรทัดโดยลำดับในเวลาที่เหมาะสมโดยใช้POSIX
ไวยากรณ์ผสานการเปลี่ยนเส้นทาง
หากแอปพลิเคชันใช้เอาต์พุตบัฟเฟอร์มันอาจเกิดขึ้นว่าข้อความของสตรีมหนึ่งถูกแทรกในอีกสตรีมที่ขอบเขตบัฟเฟอร์ซึ่งอาจปรากฏขึ้นตรงกลางของบรรทัดข้อความ
คนตัดไม้โดยเฉพาะคอนโซลเอาท์พุท (เช่น"StdOut/StdErr Logger"
โดย'LoRd MuldeR'
) อาจจะมีความน่าเชื่อถือมากขึ้นสำหรับงานดังกล่าว
ในแบตช์ไฟล์ (Windows 7 ขึ้นไป) ฉันพบว่าวิธีนี้น่าเชื่อถือที่สุด
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
เห็นได้ชัดว่าใช้คำสั่งใดก็ได้ที่คุณต้องการและผลลัพธ์จะถูกนำไปยังไฟล์ข้อความ การใช้วิธีนี้มีความน่าเชื่อถืออย่างไรก็ตามไม่มีการแสดงผลบนหน้าจอ
>con echo This goes to screen
ยังมีประโยชน์สำหรับการป้อนข้อมูลของผู้ใช้>con set /p "var="Input: "
หมายเหตุ: เส้นที่จะเพียงปรากฏบนหน้าจอและไม่ได้ถูกเปลี่ยนเส้นทางไปยังแฟ้ม