Перенаправить 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.

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

ripper234
источник
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
DelboyJay
источник
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
StormeHawke
источник
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

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

PanamaPHat
источник
(в основном тот же ответ, который был дан несколько раз назад.) Вы можете принудительно вывести вывод на экран с помощью >con echo This goes to screenТакже полезно для ввода пользователем. >con set /p "var="Input: "Примечание: эти строки будут отображаться только на экране и не будут перенаправлены в файл.
Стефан,