Перенаправить Windows cmd stdout и stderr в один файл - PullRequest
634 голосов
/ 14 сентября 2009

Я пытаюсь перенаправить весь вывод (stdout + stderr) команды DOS в один файл:

C:\>dir 1> a.txt 2> a.txt
The process cannot access the file because it is being used by another process.

Возможно ли это, или я должен просто перенаправить на два отдельных файла?

Ответы [ 7 ]

986 голосов
/ 14 сентября 2009

Вы хотите:

dir > a.txt 2>&1

Синтаксис 2>&1 перенаправит 2 (stderr) на 1 (stdout). Вы также можете скрыть сообщения, перенаправив на NUL, дополнительные пояснения и примеры на MSDN .

183 голосов
/ 23 мая 2013

Ответ Андерса Линдала правильный, но следует отметить, что если вы перенаправляете стандартный вывод в файл и хотите перенаправить также стандартный поток ошибок, то вы ДОЛЖНЫ убедиться, что указано 2>&1 ПОСЛЕ 1> перенаправить, иначе это не будет работать.

REM *** WARNING: THIS WILL NOT REDIRECT STDERR TO STDOUT ****
dir 2>&1 > a.txt

Правильный путь: dir > a.txt 2>&1. Чтобы добавить, используйте >>.

75 голосов
/ 18 октября 2013

Справочная информация от MSKB

Несмотря на то, что принятый ответ на этот вопрос правильный, он действительно мало что объясняет , почему работает, и, поскольку синтаксис не сразу понятен, я сделал быстрый Google, чтобы выяснить, что было на самом деле происходит. В надежде, что эта информация будет полезна для других, я публикую ее здесь.

Взято из MS Support KB 110930 .


Из MSKB110930

Перенаправление сообщений об ошибках из командной строки: STDERR / STDOUT

Резюме

При перенаправлении вывода из приложения с помощью символа «>» сообщения об ошибках по-прежнему выводятся на экран. Это связано с тем, что сообщения об ошибках часто отправляются в поток стандартных ошибок вместо потока стандартных выходов.

Вывод из консольного приложения (командной строки) или команды часто отправляется в два отдельных потока. Обычный вывод отправляется на стандартный выход (STDOUT), а сообщения об ошибках отправляются на стандартную ошибку (STDERR). Когда вы перенаправляете вывод консоли, используя символ «>», вы перенаправляете только STDOUT. Чтобы перенаправить STDERR, вы должны указать '2>' для символа перенаправления. Это выбирает второй поток вывода, который является STDERR.

* * Пример 1 022

Команда dir file.xxx (где file.xxx не существует) отобразит следующий вывод:

Volume in drive F is Candy Cane Volume Serial Number is 34EC-0876

File Not Found

Если вы перенаправите вывод на устройство NUL, используя dir file.xxx > nul, вы все равно увидите часть сообщения об ошибке, например:

File Not Found

Чтобы перенаправить (только) сообщение об ошибке на NUL, используйте следующую команду:

dir file.xxx 2> nul

Или вы можете перенаправить вывод в одно место, а ошибки - в другое.

dir file.xxx > output.msg 2> output.err

Вы можете распечатать ошибки и стандартный вывод в один файл, используя команду «& 1», чтобы перенаправить вывод для STDERR в STDOUT, а затем отправить вывод из STDOUT в файл:

dir file.xxx 1> output.msg 2>&1
28 голосов
/ 24 июля 2013

Чтобы добавить stdout и stderr в общий лог-файл скрипта:

dir >> a.txt 2>&1
12 голосов
/ 06 февраля 2014

Правильно, файловый дескриптор 1 для процесса - STDOUT, перенаправленный 1> или > (1 может быть опущен, условно, интерпретатор команд [cmd.exe] знает, что обработать). Файловый дескриптор 2 - STDERR, перенаправленный 2>.

Обратите внимание, что если вы используете их для создания файлов журнала, то, если вы не отправляете выход в _uniquely_named_ (например, с отметкой даты и времени), то если вы запускаете один и тот же процесс дважды, перенаправляется перезапишет (заменит) предыдущий файл журнала.

>> (для STDOUT или STDERR) APPEND не ЗАМЕНИТ файл. Таким образом, вы получаете накопительный лог-файл, показывающий результаты всех запусков процесса - как правило, более полезный.

Счастливые тропы ...

5 голосов
/ 14 сентября 2009

Я просто выбрал ответ, потому что @Anders только что опубликовал его, но ...

Из справки Windows я произвел поиск перенаправления (URL ms-it: C: \ WINDOWS \ Help \ ntcmds.chm :: / redirection.htm ).

Возможно, вы захотите прочитать о >> и | (труба) тоже.

1 голос
/ 27 февраля 2018

Однако нет никакой гарантии, что выходные данные SDTOUT и STDERR будут переплетены построчно в своевременном порядке с использованием синтаксиса перенаправления слияния POSIX.

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

Выделенный консольный регистратор вывода (например, «StdOut / StdErr Logger» от LoRd MuldeR) может быть более надежным для такой задачи. См .: Проекты с открытым исходным кодом MuldeR

...