การเขียนเอาต์พุตคำสั่งใน 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

คำตอบ:


22

คุณไม่ได้แสดงคำสั่งที่คุณใช้ซึ่งล้มเหลว หากคุณแสดงในคำถามของคุณมันอาจจะง่ายกว่าที่จะหาวิธีแก้ปัญหาสำหรับคุณ

ฉันคาดว่าคำสั่งของคุณจะเป็นเช่นนี้:

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' ...

เมื่อระบุชื่อไฟล์ (หรือพา ธ ) ที่มีช่องว่างคุณต้องล้อมรอบด้วยเครื่องหมายอัญประกาศคู่ ( "...") ทั้งนี้เพราะเมื่อระบบปฏิบัติการคือการกำหนดไฟล์ที่จะเปลี่ยนเส้นทางไปก็จะหยุดมองหาชื่อไฟล์เมื่อพบพื้นที่ "c:/Program"unquoted:

ลองสิ่งนี้:

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

นี่เป็นวิธีการ "ย่อ" ในการระบุและหมายถึงการเปลี่ยนเส้นทางสตรีม 1 ไปยังไฟล์ที่ระบุและเพื่อเปลี่ยนเส้นทางสตรีม 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"ที่>เป็นสาเหตุที่ทำให้การส่งออกที่จะเขียนไปยังใหม่แฟ้มที่ชื่อ "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ปรากฏขึ้นบนหน้าจอ ... นี่เป็นพฤติกรรมที่คาดหวัง

ตอนนี้ใช้การเปลี่ยนเส้นทางทั้งสอง ("> ไฟล์" และ "2> ไฟล์"):

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 ไบต์) และผลลัพธ์สำหรับการเปลี่ยนเส้นทางทั้งคู่ก็หายไป

สุดท้ายนี้ใช้ทั้งการเปลี่ยนเส้นทาง ("> ไฟล์" และ "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>

ในกรณีนี้ "> ไฟล์" เป็นสาเหตุให้เอาต์พุตสำหรับ "สตรีม 1" ("เอาต์พุตมาตรฐาน") เพื่อบันทึกลงไฟล์ และ "2> & 1" ทำให้เอาต์พุตสำหรับ "สตรีม 2" ("เอาต์พุตข้อผิดพลาด") ถูกส่งผ่าน "สตรีม 1" ที่ถูกเปลี่ยนเส้นทางแล้วและจะถูกจับไปยังไฟล์ (เดียวกัน) ด้วย

นอกจากนี้ยังเป็นที่น่าสังเกตว่าลำดับสำคัญ กลับคำสั่งเช่นนี้:

dir nonexistant 2>&1 >output.txt

ไม่เหมือนกันและอาจไม่ให้ผลลัพธ์ที่ต้องการ

ในกรณีนี้ "2> & 1" ซึ่งถูกมองเห็นและ precessed ก่อนทำให้เอาต์พุตสำหรับ "สตรีม 2" ("ข้อผิดพลาดเอาต์พุต") ถูกเปลี่ยนเส้นทางไปยังตำแหน่งที่ปัจจุบัน "สตรีม 1" ถูกนำทางไปยังตำแหน่งที่อยู่นั้น ขณะนี้คือ (โดยค่าเริ่มต้น) หน้าจอ และ "> ไฟล์" ทำให้เอาต์พุตสำหรับ "สตรีม 1" ("เอาต์พุตมาตรฐาน") ถูกบันทึกลงไฟล์ ผลลัพธ์สุดท้ายคือผลลัพธ์ของคำสั่ง ("สตรีม 1") จะถูกบันทึกลงในไฟล์ แต่เอาต์พุตข้อผิดพลาด ("สตรีม 2") จะยังคงไปที่หน้าจอ (ไม่ใช่ไฟล์)


ปรากฎว่าfoo.exe>"c:\test.txt"ใช้งานได้จริง แต่มันโยนข้อผิดพลาดที่โปรแกรมขัดข้อง (ผลลัพธ์ยังคงอยู่ที่นั่น) อย่างไรก็ตามข้อเสนอแนะของคุณทำให้ดียิ่งขึ้นเนื่องจาก2>&1ข้อร้องเรียนการขัดข้องหายไป สนใจที่จะอธิบายรายละเอียดเกี่ยวกับสิ่งที่มันทำ? ขอบคุณอีกครั้งสำหรับคำตอบที่ดี
pzkpfw

@ bigbadonk420 - 2>&1ฉันปรับปรุงคำตอบของฉันที่จะมีข้อมูลเกี่ยวกับการใช้งานของ หากคุณตรวจสอบไฟล์ "c: \ test.txt" คุณจะเห็นว่ามีการเขียน"การร้องเรียนขัดข้อง"ลงในไฟล์ 2>&1ไม่ควรทำให้หรือป้องกันไม่ให้โปรแกรมหยุดทำงานมันแค่ทำให้ข้อความแสดงข้อผิดพลาดถูกจับแทนที่จะแสดง
Kevin Fegan

1
ด้วยเหตุผลบางอย่างมันทำ
pzkpfw

1
@ bigbadonk420 - การ'for some reason it does'เปลี่ยนเส้นทางในทางใดบ้าง คุณกำลังบอกว่าเมื่อคุณเปลี่ยนเส้นทางรวมถึง2>&1ข้อผิดพลาดที่ไม่เกิดขึ้น? คุณเห็นข้อความแสดงข้อผิดพลาดอะไรเมื่อเกิดข้อผิดพลาด
Kevin Fegan

1
เมื่อ2>&1ไม่รวมโปรแกรมจะขัดข้องและฉันได้รับ Windows "กล่องโต้ตอบโปรแกรมนี้หยุดตอบสนอง" เมื่อฉันรวมมันไม่ได้ ไม่รู้ว่าทำไม แม้ว่าจะสร้างผลลัพธ์ในทั้งสองกรณี
pzkpfw
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.