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, он просто не будет хорошо печататься в файл. Очевидно, что выход есть, вопрос в том, есть ли какой-нибудь способ его поймать.

1 ответ1

21

Вы не показали команду, которую вы используете, которая не работает. Если вы покажете это в своем вопросе, возможно, вам будет легче найти решение.

Я ожидаю, что ваша команда примерно такая:

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-Output. Обычно программы записывают свой "нормальный" вывод в поток 1.

  2. Поток 2 называется STDERR или Standard-Error. Обычно программы записывают свои выходные данные "Error" (сообщения об ошибках и предупреждения) в поток 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), этот вывод не будет записан и будет показан на экране. Как правило, это "желательный" способ сделать это так, чтобы во время захвата нормального вывода программы вы могли видеть на экране, если произошла ошибка.

Если вы хотите записать вывод "Normal" в один файл, а вывод "Error" в другой файл, вы можете сделать это следующим образом:

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

Если вы хотите, чтобы вывод "Normal" и вывод "Error" были записаны в один и тот же файл, вы можете указать его следующим образом:

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>

В этом случае операционная система жаловалась, что (выходной) файл уже используется. И файл «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", что при этом моментом является (по умолчанию) экран. И «> file» приводит к тому, что вывод для "stream 1" ("стандартный вывод") записывается в файл. Конечным результатом является то, что вывод команды ("поток 1") будет записан в файл, но вывод ошибок ("поток 2") все равно будет отображаться на экране (а не в файле).

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .