Windows cmd'de komut çıktısını bir dosyaya yazma (bir bükülme ile)


9

Bu yüzden çalıştırmaya çalışıyorum foo.exe, ama terminale değil bir dosyaya çıktı istiyorum. Koşmak foo.exe > foo.txtbunu benim için başarmalı ama değil. Exe dosyasını çalıştırdığımda çıktıyı alıyorum. Exe başka bir deyişle iyi çalışıyor. Ancak, çıktıyı bir dosyaya göndermeye çalıştığımda, aldığım tek şey şudur:

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

Bu sadece bir dosyaya göndermeye çalıştığımda ortaya çıkıyor. c:\Program Files (x86)\Yanlış yorumlanabilen yol ( ve benzeri) olabileceğini düşünerek , çıktı dosyasını şöyle belirtmeye çalıştım: foo.exe > c:\test.txtama yine de neşe yok.

Yani, çalıştırmaya çalıştığım ikili kodun kötü yazıldığını belirtmenin yanı sıra, bunu düzeltmek için yapabileceğim bir şey var mı? Sadece exe çalıştırırken geçerli çıktı almak olduğunu unutmayın, sadece bir dosyaya güzel yazdırmaz. Açıkçası çıktı orada, soru onu yakalamanın bir yolu olup olmadığı.


Programı basit bir dizine (C: \ Simple veya hatta C: \) taşırsanız ve bunları oradan denerseniz ne olur?
Jan Doggen

Yanıtlar:


22

Kullandığınız komutun başarısız olduğunu göstermediniz. Sorunuzda gösterirseniz, sizin için bir çözüm bulmak daha kolay olabilir.

Komutunun böyle bir şey olmasını bekliyorum:

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

Aldığınız hata bir ipucu:

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

İlk:
... is not recognized as an internal or external command, operable program or batch file.

Bu genellikle a |yerine bir dosyaya yeniden yönlendirmeye çalıştığınızda olur >.

İkinci:
'c:/Program' ...

Boşluk içeren bir dosya adı (veya yol) belirtirken, dosyayı çift tırnak işareti ( "...") içine almanız gerekir . Bunun nedeni, işletim sisteminin yönlendirilecek dosyayı belirlemesi durumunda, aktarılmamış bir alanla karşılaştığında dosya adını aramayı durdurmasıdır "c:/Program".

Bunu dene:

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



Yukarıdakiler foo.exe, metin dosyasından çıktıyı yakalamak için çalışmazsa , başka bir olasılık daha vardır ...

Program Eğer foo.exeonun çıkışını yazıyor STDERRyerine STDOUT, çıkış foo.exetek basit yeniden yönlendirme kullanılarak yakalanmaz >. Bunu şu şekilde yapmanız gerekir:

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



Düzenle:

İşte dosya yönlendirme ve 2>&1gösterimi ile ilgili bir açıklama .

Bir program terminale yazdığında, ikisinden birine yazabilir Streams.

  1. Akış 1 STDOUTveya Standart Çıkış olarak adlandırılır . Tipik olarak, programlar "Normal" çıkışlarını akış 1'e yazar.

  2. Akış 2 STDERRveya Standart Hata olarak adlandırılır . Genellikle, programlar "Hata" çıkışlarını (hata ve uyarı mesajları) akış 2'ye yazar.

Bir programın belirli bir çıktıyı yazıp yazmadığı STDOUTveya STDERRprogramcı tarafından belirlendiği ve programı nasıl yazdığı. Tüm programlar (normal çıktı ve hatalar) 'a göndermek için bazı programlar yazılır STDOUT.

Bir program çıkış yeniden yönlendirmesi olmadan çalıştırıldığında, tüm normal ve hata çıkışları, STDOUTçıkış veya STDERRçıkış arasındaki fark olmadan terminal ekranına gönderilir .

Bunun >gibi bir tekle "normal" yönlendirme yaptığınızda :

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

hangi Akış'ın dosyaya yönlendirileceğini belirtmediğiniz için Akış 1 olduğu varsayılır.

Bu şekilde yazdığınız gibi:

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

Bu, komut yorumlayıcısına ( cmd.exe) STDOUTbelirtilen dosya adına (Akış 1) için program çıktısını yakalamasını söyler . 1Bölgesindeki 1>Akış 1 anlamına gelir.

Bu durumda, tüm normal program dosyaya kaydedilir, ancak program STDERR(Akış 2) 'ye yazarsa, bu çıktı yakalanmaz ve ekranda gösterilir. Bu genellikle bunu yapmak için "istenen" yoldur, böylece normal program çıktısını yakalarken bir hata oluşursa ekranda görebilirsiniz.

Bir dosyaya "Normal" çıktısını ve farklı bir dosyaya "Hata" çıktısını yakalamak istiyorsanız, bunu şu şekilde yapabilirsiniz:

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

"Normal" çıktı ile "Hata" çıktısının aynı dosyaya kaydedilmesini istiyorsanız, bunu şu şekilde belirtebilirsiniz:

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

Bu temel olarak belirtmenin "kısayol" yoludur ve Akış 1'i belirtilen dosyaya yeniden yönlendirmek ve Akış 2'yi Akış 1 ile aynı "yer" (dosya) ' ya yeniden yönlendirmek anlamına gelir .


Düzenle:

Pacerier sordu:

Foo.exe> ​​"c: \ output.txt" 2> & 1 ve foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt" arasında herhangi bir fark var mı? Aynı mı?

Kısa cevap: Aynı olduklarını düşünürdünüz, ama hayır. Onlar farklı.

Yönlendirme kullanarak sayesinde >"filename.ext", 1>"filename.ext"ya 2>"filename.ext", >çıkış bir yazılmasına neden olan yeni "dosyaadi.uzanti" adlı dosyada. "Filename.ext" dosyası zaten varsa, önce silinir.

Yani, kullanarak:

foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"

her iki yönlendirmenin de aynı dosyaya yazmaya çalıştığı ve her ikisi de zaten varsa dosyayı silmeye çalıştığı bir "çakışmaya" neden olur. Bu muhtemelen istenmeyen davranışlara neden olacaktır. Genellikle, çıkışlardan biri veya diğeri veya her ikisi birden tam olarak veya öngörülebilir şekilde yakalanmayacaktır.

Gerçek sonuç işletim sistemine ve sürüme ve ayrıca yürütülmekte olan komuta da bağlı olabilir. Muhtemelen ne olacak:

1 Yeniden yönlendirmelerden birine gönderilen çıktı yakalanır veya kısmen yakalanır ve diğer yeniden yönlendirmelere gönderilen çıktı kaybedilir. 2 İşletim sistemi komuttan şikayet edecek ve çıkışlardan hiçbiri yakalanmayacak (tamamen). 3 Tanımsız, istenmeyen, öngörülemeyen, beklenmedik davranış.

Windows 7'de ve muhtemelen Windows Vista / 8 / 10'da ve muhtemelen Windows XP'de, işletim sistemi komuttan şikayet edecek ve komut iptal edilecektir.

Örneğin (Windows 7):: adında bir klasörüm var "C:\Temp\emptyfolder"ve "nonexistantfile" adında bir dosya yok.

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>

Bu durumda, bir yönlendirme ( >output.txt) kullanarak , dirkomutun çıktısı şu dosyayı yakalar: output.txtve hata mesajı File Not Foundekranda gösterilir ... bu beklenen davranıştır.

Şimdi, her iki yönlendirmeyi kullanarak ("> dosya" AND "2> dosya"):

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>

Bu durumda, işletim sistemi (outout) dosyasının zaten kullanımda olduğundan şikayet ediyordu. Ve "output.txt" dosyası boş kalır (0 bayt) ve her iki yönlendirme için de çıktı kaybedilir.

Son olarak, her iki yönlendirmeyi kullanarak ("> dosya" 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>

Bu durumda, "> dosya", "akış 1" ("standart çıktı") çıktısının dosyaya alınmasına neden olur. Ve "2> & 1", "akış 2" ("hata çıkışı") için çıktının önceden yönlendirilmiş "akış 1" yoluyla gönderilmesine ve aynı zamanda (aynı) dosyaya yakalanmasına neden olur.

Siparişin önemli olduğunu da belirtmek gerekir. Sırayı şu şekilde tersine çevirmek:

dir nonexistant 2>&1 >output.txt

aynı değildir ve muhtemelen size istenen sonucu vermeyecektir.

Bu durumda, önce görülen ve önceden hazırlanan "2> & 1", "akış 2" ("hata çıkışı") çıkışının "akış 1" in yönlendirildiği yere yönlendirilmesine neden olur. (varsayılan olarak) ekran. Ve "> dosya", "akış 1" ("standart çıktı") çıktısının dosyaya alınmasına neden olur. Sonuç olarak, komutun çıktısı ("akış 1") dosyaya kaydedilir, ancak hata çıktısı ("akış 2") yine de ekrana (dosyaya değil) gider.


Çıkıyor bu foo.exe>"c:\test.txt"aslında çalışmış, ancak programın (çıkış olsa hâlâ orada) çöktü bir hata attı. Ancak, 2>&1kaza şikayeti giderken öneri daha da iyi yaptı. Ne yaptığına dikkat etmek ister misiniz? Harika bir cevap için tekrar teşekkürler.
pzkpfw

@ bigbadonk420 - Cevabımın kullanımı hakkında bilgi içerecek şekilde güncelledim 2>&1. "C: \ test.txt" dosyanızı incelerseniz, büyük olasılıkla "kilitlenme şikayetinin" dosyaya yazıldığını görürsünüz . 2>&1programın kilitlenmesine neden olmamalı veya engellenmemelidir, sadece hata mesajlarının görüntülenmek yerine yakalanmasına neden olur.
Kevin Fegan

1
Nedense öyle.
pzkpfw

1
@ bigbadonk420 - 'for some reason it does'yeniden yönlendirmeden ne şekilde etkileniyor? İçeriği yeniden yönlendirdiğinizde 2>&1hatanın oluşmadığını mı söylüyorsunuz? Hata oluştuğunda hangi hata mesajını görüyorsunuz?
Kevin Fegan

1
Ne zaman 2>&1dahil değildir, program çöker ve standart Windows "bu program yanıt vermeyi durdurdu" iletişim kutusu alıyorum. Onu dahil ettiğimde içermez. Neden olduğu hakkında bir fikrim yok. Her iki durumda da çıktı üretilir.
pzkpfw
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.