Menulis output perintah di Windows cmd ke file (dengan twist)

9

Jadi saya mencoba untuk menjalankan foo.exe, tetapi saya tidak ingin output ke terminal tetapi menjadi file. Berlari foo.exe > foo.txtharus menyelesaikan ini untukku, tetapi ternyata tidak. Ketika saya menjalankan file exe, saya mendapatkan output. Exe bekerja dengan baik dengan kata lain. Namun, ketika saya mencoba mengirim output ke file, satu-satunya hal yang saya dapatkan adalah ini:

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

Ini hanya muncul ketika saya mencoba mengirimnya ke file. Berpikir bahwa itu bisa menjadi jalan (yang ada c:\Program Files (x86)\dan sebagainya) yang disalahtafsirkan, saya mencoba menentukan file output seperti:, foo.exe > c:\test.txttetapi masih tidak ada sukacita.

Jadi, selain menyatakan bahwa biner yang saya coba jalankan tidak ditulis dengan baik, adakah yang bisa saya lakukan untuk memperbaiki ini? Perlu diingat bahwa saya mendapatkan output yang valid ketika hanya menjalankan exe, itu tidak akan mencetak dengan baik ke file. Jelas hasilnya ada di sana, pertanyaannya adalah apakah ada cara untuk menangkapnya.

pzkpfw
sumber
Apa yang terjadi jika Anda memindahkan program ke direktori sederhana (C: \ Simple atau bahkan C: \) dan mencoba hal-hal ini dari sana?
Jan Doggen

Jawaban:

21

Anda belum menunjukkan perintah yang Anda gunakan yang gagal. Jika Anda menunjukkannya dalam pertanyaan Anda, mungkin akan lebih mudah untuk menemukan solusi untuk Anda.

Saya berharap perintah Anda adalah sesuatu seperti ini:

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

Kesalahan yang Anda terima agak merupakan petunjuk:

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

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

Ini biasanya terjadi ketika Anda mencoba mengalihkan ke file menggunakan |bukan >.

Kedua:
'c:/Program' ...

Saat menentukan nama file (atau jalur) yang berisi spasi, Anda harus mengelilinginya dalam tanda kutip ganda ( "..."). Hal ini karena ketika OS adalah menentukan file untuk mengarahkan ke, itu akan berhenti mencari nama file ketika bertemu ruang kuotasi: "c:/Program".

Coba ini:

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



Jika hal di atas tidak berfungsi untuk menangkap output dari foo.exeke file teks, maka ada kemungkinan lain ...

Jika program foo.exemenulis outputnya STDERRsebagai ganti STDOUT, output foo.exetidak akan ditangkap dengan menggunakan pengalihan sederhana dengan satu >. Anda harus melakukannya seperti ini:

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



Edit:

Berikut adalah penjelasan pengalihan file dan 2>&1notasi.

Ketika sebuah program menulis ke terminal, ia dapat menulis ke salah satu dari dua Streams.

  1. Stream 1 disebut sebagai STDOUTatau Output-Standar . Biasanya, program menulis output "Normal" untuk streaming 1.

  2. Stream 2 disebut sebagai STDERRatau Kesalahan Standar . Biasanya, program menulis output "Kesalahan" (pesan kesalahan dan peringatan) untuk streaming 2.

Apakah suatu program menulis output tertentu STDOUTatau STDERRditentukan oleh programmer dan bagaimana mereka menulis program tersebut. Beberapa program ditulis untuk mengirim semua output (output dan kesalahan normal) ke STDOUT.

Ketika suatu program dijalankan tanpa redirection output, semua output normal dan error dikirim ke layar terminal tanpa ada perbedaan antara apa itu STDOUToutput atau STDERRoutput.

Ketika Anda melakukan pengalihan "normal" dengan satu >seperti ini:

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

Anda tidak menentukan Stream mana yang sedang dialihkan ke file, jadi Stream 1 diasumsikan.

Sama seperti jika Anda mengetiknya seperti ini:

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

Ini memberi tahu juru bahasa perintah ( cmd.exe) untuk menangkap keluaran program untuk STDOUT(Aliran 1) ke nama file yang ditentukan. The 1dalam 1>mengacu Streaming 1.

Dalam hal ini semua program normal ditangkap ke file, tetapi jika program menulis ke STDERR(Stream 2), output itu tidak akan ditangkap dan akan ditampilkan di layar. Ini umumnya merupakan cara "yang diinginkan" untuk melakukannya sehingga saat Anda menangkap keluaran program normal, Anda dapat melihat di layar jika terjadi kesalahan.

Jika Anda ingin menangkap output "Normal" ke satu file, dan "Error" output ke file lain Anda dapat melakukannya seperti ini:

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

Jika Anda ingin "Normal" output dan "Kesalahan" output yang akan diambil ke yang sama file, Anda dapat menentukan seperti ini:

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

Ini pada dasarnya adalah cara "singkatan" untuk menentukannya dan itu berarti mengarahkan Aliran 1 ke file yang ditentukan, dan juga mengarahkan Aliran 2 ke "tempat" (file) yang sama dengan Aliran 1.


Edit:

Pacerier bertanya:

Apakah ada perbedaan antara foo.exe> ​​"c: \ output.txt" 2> & 1 dan foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"? Apakah mereka identik?

Jawaban singkat: Anda akan berpikir mereka identik, tetapi tidak. Mereka berbeda.

Dengan redirection menggunakan >"filename.ext",, 1>"filename.ext"atau 2>"filename.ext", >menyebabkan output ditulis ke file baru bernama "filename.ext". Jika file "filename.ext" sudah ada, itu akan dihapus terlebih dahulu.

Jadi, menggunakan:

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

menyebabkan "konflik" di mana kedua pengalihan berusaha menulis ke file yang sama dan keduanya mencoba untuk menghapus file jika sudah ada. Ini kemungkinan akan menyebabkan perilaku yang tidak diinginkan. Umumnya, satu atau yang lain, atau keduanya, dari output TIDAK akan ditangkap sepenuhnya, atau dapat diprediksi.

Hasil aktual akan tergantung pada sistem operasi dan versi, dan mungkin juga tergantung pada perintah yang dieksekusi. Apa yang kemungkinan akan terjadi adalah:

1 Output yang dikirim ke salah satu pengalihan akan ditangkap atau ditangkap sebagian, dan output yang dikirim ke pengalihan lainnya akan hilang. 2 Sistem operasi akan mengeluh tentang perintah dan tidak satu pun dari output akan ditangkap (sepenuhnya). 3 Perilaku yang tidak terdefinisi, tidak diinginkan, tidak terduga, tak terduga.

Pada Windows 7 dan kemungkinan pada Windows Vista / 8/10, dan mungkin pada Windows XP, sistem operasi akan mengeluh tentang perintah dan perintah akan dibatalkan.

Sebagai contoh (Windows 7): Saya memiliki folder bernama: "C:\Temp\emptyfolder"dan file bernama "nonexistantfile" tidak ada di sana.

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>

Dalam kasus ini, dengan menggunakan satu pengalihan ( >output.txt), output dari dirperintah ditangkap file:, output.txtdan pesan kesalahan File Not Foundditampilkan di layar ... ini adalah perilaku yang diharapkan.

Sekarang, menggunakan kedua pengalihan ("> file" DAN "2> file"):

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>

Dalam hal ini, sistem operasi mengeluh bahwa file (keluar) sudah digunakan. Dan file "output.txt" berakhir kosong (0 byte), dan output untuk kedua pengalihan hilang.

Sekarang, terakhir, menggunakan kedua pengalihan ("> file" 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>

Dalam hal ini, "> file" menyebabkan output untuk "stream 1" ("output standar") ditangkap ke file. Dan "2> & 1" menyebabkan output untuk "stream 2" ("output error") dikirim melalui "stream 1" yang sudah diarahkan, dan juga akan ditangkap ke file (sama).

Perlu juga dicatat bahwa urutan itu penting. Membalik urutan seperti ini:

dir nonexistant 2>&1 >output.txt

tidak sama dan mungkin tidak akan memberi Anda hasil yang diinginkan.

Dalam kasus ini, "2> & 1", yang dilihat dan didahului terlebih dahulu, menyebabkan output untuk "stream 2" ("output error") dialihkan ke tempat "stream 1" saat ini diarahkan ke, yang pada saat itu saat, adalah (secara default), layar. Dan "> file" menyebabkan output untuk "stream 1" ("output standar") ditangkap ke file. Hasil akhirnya, adalah bahwa output dari perintah ("stream 1") akan ditangkap ke file, tetapi output kesalahan ("stream 2"), masih akan pergi ke layar (bukan ke file).

Kevin Fegan
sumber
Ternyata itu foo.exe>"c:\test.txt"benar - benar bekerja, tetapi melemparkan kesalahan bahwa program macet (output masih ada). Namun, saran Anda membuatnya lebih baik karena 2>&1keluhan macetnya hilang. Ingin menguraikan apa yang dilakukannya? Sekali lagi terima kasih atas jawaban yang bagus.
pzkpfw
@ bigbadonk420 - Saya memperbarui jawaban saya untuk memasukkan informasi tentang penggunaan 2>&1. Jika Anda memeriksa file Anda "c: \ test.txt", kemungkinan besar Anda akan melihat bahwa "keluhan macet" telah ditulis ke file tersebut. 2>&1seharusnya tidak menyebabkan atau mencegah program mogok, itu hanya menyebabkan pesan kesalahan ditangkap daripada ditampilkan.
Kevin Fegan
1
Ya, untuk beberapa alasan.
pzkpfw
1
@ bigbadonk420 - 'for some reason it does'dengan cara apa itu dipengaruhi oleh pengalihan? Apakah Anda mengatakan bahwa ketika Anda mengalihkan termasuk 2>&1, bahwa kesalahan tidak terjadi? Apa pesan kesalahan yang Anda lihat ketika kesalahan terjadi?
Kevin Fegan
1
Ketika 2>&1tidak disertakan, program macet dan saya mendapatkan dialog standar Windows "program ini telah berhenti merespons". Ketika saya memasukkannya, itu tidak. Tidak tahu kenapa. Output dihasilkan dalam kedua kasus.
pzkpfw