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

557

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

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

Теги:
cmd
command-line
pipe

7 ответов

876
Лучший ответ

Вы хотите:

dir > a.txt 2>&1

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

  • 25
    спасибо за это, не знал, что этот синтаксис оболочки Unix работает и для DOS!
  • 16
    это отлично подходит для сокрытия всех выходных данных .. net stop w3svc >NUL 2>&1 .. спасибо!
Показать ещё 7 комментариев
177

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

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

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

  • 8
    ПОСЛЕ того, что стоило мне часов, чтобы выяснить, что не так DelboyJay! Спасибо!
  • 4
    Объясняется ли где-нибудь, почему размещение 2> & 1 перед 1> не приведет к желаемому эффекту? Я сильно подозреваю, что это связано с тем, как "cmd" анализирует команды, которые дают два разных значения в зависимости от порядка, в котором вы указываете перенаправление. Но задокументированы ли семантические правила где угодно, потому что я считаю, что это стоит изучить, так как это может потратить часы.
Показать ещё 11 комментариев
66

Фоновая информация от MSKB

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

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


От MSKB110930

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

Резюме

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

Вывод приложения или команды консоли (Command Prompt) часто отправляется в два отдельных потока. Регулярный вывод отправляется в стандартный выход (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
22

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

dir >> a.txt 2>&1
  • 7
    >> добавляет к файлу, где > перезаписывает файл.
12

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

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

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

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

4

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

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

Вы можете прочитать о → и | (труба) тоже.

0

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню