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

Чи це можливо, або я повинен просто переадресувати на два окремих файли?


14
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не.
The Red Pea

9
Я так люблю ТАК "Фу, ця маленька разова проблема займе як годину". Щоб зайняти цю відповідь, мені знадобилося більше часу, ніж це було.
Брендон

195

Відповідь Андерса Ліндаль є правильним, але слід зазначити , що якщо ви перенаправляти стандартний висновок в файл і хочете , щоб перенаправити потік помилок, а потім ви повинні переконатися , що 2>&1зазначено ПІСЛЯ в 1>редирект, в іншому випадку він не буде працювати.

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

10
ПІСЛЯ те, що коштувало мені годин, щоб зрозуміти, що не так DelboyJay! Дякую!
Нам Г ВУ

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). Потім, після того, як вони вже об'єднані, ви перенаправляєте stdout ( >без специфікатора) у файл. Якщо ви хочете, щоб stderr пішов кудись інше, ви не можете спочатку приєднатись до stdout.
cp.engr

80

Довідкова інформація від MSKB

Незважаючи на те, що прийнята відповідь на це питання є правильною, він насправді не дуже багато пояснює, чому це працює, і оскільки синтаксис не відразу зрозумілий, я зробив швидкий google, щоб дізнатися, що відбувається насправді. Сподіваючись, що ця інформація буде корисною для інших, я її розміщую тут.

Взяте з MS Підтримка KB 110930 .


Від MSKB110930

Перенаправлення повідомлень про помилки з командного рядка: STDERR / STDOUT

Підсумок

Під час перенаправлення виводу з програми за допомогою символу '>' повідомлення про помилки все ще друкуються на екран. Це відбувається тому, що повідомлення про помилки часто надсилаються до потоку Standard Error замість потоку Standard Out.

Вихід з консольного (командного рядка) програми чи команди часто надсилається до двох окремих потоків. Звичайний вихід надсилається в стандартний вихід (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.