Перенаправить Windows cmd stdout и stderr в один файл


688

Я пытаюсь перенаправить весь вывод (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.

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


15
TechNet. Использование операторов перенаправления команд (ответы на них лучше, чем на любые другие ответы здесь).
— Мартин Прикрыл

1
2> & 1, поскольку он не может открыть один и тот же файл
— Лука

Ответы:


1090

Ты хочешь:

dir > a.txt 2>&1

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


32
спасибо за это, не знал, что этот синтаксис оболочки Unix работает и для DOS!
— Chaindriver

20
это отлично подходит для сокрытия всего вывода .. net stop w3svc >NUL 2>&1.. спасибо!
— wasatchwizard

3
@ wasatchwizard Я думаю, у меня были проблемы с этим, но> NUL 2> NUL работал нормально
— FrinkTheBrave

13
Если есть дескриптор, между дескриптором (т. Е. 2) и оператором перенаправления (т. Е.>) Не должно быть пробела. Поэтому 2> 2.txtработает (или 2> &1) 2 > 2.txtнет; 2 > &1не.
— Красный горох

9
Я так сильно люблю. «Тьфу, эта маленькая разовая проблема займет около часа». Мне потребовалось больше времени, чтобы напечатать этот комментарий, чем найти этот ответ.
— Брэндон

195

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

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

10
ПОСЛЕ того, что стоило мне часов, чтобы выяснить, в чем дело DelboyJay! Спасибо!
— Нам G VU

4
Объясняется ли где-нибудь, почему размещение 2> & 1 перед 1> не приведет к желаемому эффекту? Я сильно подозреваю, что это связано с тем, как "cmd" анализирует команды, которые дают два разных значения в зависимости от порядка, в котором вы указываете перенаправление. Но задокументированы ли семантические правила где-нибудь, потому что я считаю, что это стоит изучить, так как это может потратить часы.
— igbgotiz

12
@igbgotiz 2> & 1 означает «перенаправить поток 2 в поток 1». Поэтому вам нужно сначала настроить поток 1
— FrinkTheBrave

3
@FrinkTheBrave, но поток 1 - это стандартный вывод (например, консоль), если он не указан явно. Это до сих пор не объясняет это имхо.
— MarioDS

1
@MDeSchaepmeester, если вы это сделаете dir 2>&1 > a.txt, вы сначала перенаправите ( >) поток 2 (stderr) на поток 1 (stdout). Затем, после того, как они оба уже объединены, вы перенаправляете стандартный вывод ( >без спецификатора) в файл. Если вы хотите, чтобы stderr пошел куда-то еще, вы не можете сначала присоединиться к нему с помощью stdout.
— cp.engr

80

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

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

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


От MSKB110930

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

Резюме

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

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

пример

Команда 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

29

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

dir >> a.txt 2>&1

9
>>Присоединяет к файлу , в котором >перезаписывает файл.
— delliottg

13

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

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

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

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


2

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

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

Выделенный вывод на консоль регистратор (т.е. с "StdOut/StdErr Logger"помощью 'LoRd MuldeR') могут быть более надежными для такой задачи.

Смотрите: Проекты с открытым исходным кодом MuldeR


0

В пакетном файле (Windows 7 и выше) я нашел этот метод наиболее надежным

Call :logging >"C:\Temp\NAME_Your_Log_File.txt" 2>&1
:logging
TITLE "Logging Commands"
ECHO "Read this output in your log file"
ECHO ..
Prompt $_
COLOR 0F

Очевидно, используйте любые команды, которые вы хотите, и вывод будет направлен в текстовый файл. С помощью этого метода является надежным Однако нет никакого вывода на экран.


(в основном тот же ответ, который был дан несколько раз назад.) Вы можете принудительно вывести вывод на экран с помощью >con echo This goes to screenТакже полезно для ввода пользователем. >con set /p "var="Input: "Примечание: эти строки будут отображаться только на экране и не будут перенаправлены в файл.
— Стефан,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.