Написання командного виводу у 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: \) і спробувати ці речі звідти?
Ян Догген

Відповіді:


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

Спробуйте це:

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або Standard-вихід . Зазвичай програми записують свій "Нормальний" вихід у потік 1.

  2. Потік 2 називається STDERRабо Standard помилок . Зазвичай програми записують свій вихід "Помилка" (повідомлення про помилки та попередження) в потік 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.


Редагувати:

Пейсьєр запитав:

Чи є різниця між 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", який бачиться і попередньо обробляється спочатку, призводить до того, що висновок для "потоку 2" ("помилка виводу") буде перенаправлений на місце, куди в даний момент спрямований "потік 1", на що Момент, це (за замовчуванням) екран. І "> файл" призводить до того, що вихід для "потоку 1" ("стандартний вихід") буде захоплений у файл. Кінцевим результатом є те, що вихід команди ("потік 1") буде зафіксований у файл, але вихід помилки ("потік 2") все одно перейде на екран (не у файл).


Виявляється, що foo.exe>"c:\test.txt"насправді спрацювало, але це призвело до помилки, що програма вийшла з ладу (вихід все ще був там). Однак ваша пропозиція зробила це ще краще, оскільки 2>&1подана скарга про аварійну ситуацію відходила. Хочете уточнити, що це робить? Ще раз дякую за чудову відповідь.
pzkpfw

@ bigbadonk420 - я оновив свою відповідь, щоб включити інформацію про використання 2>&1. Якщо ви вивчите ваш файл "c: \ test.txt", ви, швидше за все, побачите, що "скарга на збій" була записана у файл. 2>&1не повинно викликати або запобігати збоям програми, вона просто спричиняє захоплення повідомлень про помилки, а не відображення.
Кевін Феган

1
Ну, чомусь це робить.
pzkpfw

1
@ bigbadonk420 - 'for some reason it does'яким чином на це впливає перенаправлення? Ви говорите, що при переадресації в тому числі 2>&1помилка не виникає? Яке повідомлення про помилку ви бачите, коли виникає помилка?
Кевін Феган

1
Якщо 2>&1програма не включена, програма виходить з ладу, і я отримую стандартне діалогове вікно "ця програма перестала реагувати". Коли я включаю його, це не так. Не знаю, чому. Вихід генерується в обох випадках.
pzkpfw
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.