Перенаправлення вихідних даних у пакетному файлі


110

Я створюю пакетний файл з деякими простими командами для збору інформації з системи. Пакетний файл містить команди для отримання часу, інформації про IP, користувачів тощо.

Я зібрав всі команди в пакетному файлі, і він працює, але я хотів би, щоб пакетний файл під час запуску виводив результати в текстовий файл (журнал). Чи є команда, яку я можу додати до групи, яка б це зробила?

Майте на увазі, я не хочу запускати пакет з cmd, а потім перенаправляти вихід; Я хочу перенаправити вихід зсередини партії, якщо це можливо.

Відповіді:


161

Простий наївний спосіб, який повільний, тому що він відкриває та розміщує вказівник файлу на End-Of-File кілька разів.

@echo off
command1 >output.txt
command2 >>output.txt
...
commandN >>output.txt

Кращий спосіб - простіше писати та швидше, оскільки файл відкривається та розміщується лише один раз.

@echo off
>output.txt (
  command1
  command2
  ...
  commandN
)

Ще один хороший та швидкий спосіб, який відкриває та розміщує файл лише один раз

@echo off
call :sub >output.txt
exit /b

:sub
command1
command2
...
commandN

Редагувати 2020-04-17

Раз у раз ви можете неодноразово писати у два чи більше файли. Можливо, вам також потрібні різні повідомлення на екрані. Це все ще можливо зробити це ефективно, перенаправляючи на невизначені ручки за межами круглого блоку або підпрограми, а потім використовувати &позначення для посилання на вже відкриті файли.

call :sub 9>File1.txt 8>File2.txt
exit /b

:sub
echo Screen message 1
>&9 File 1 message 1
>&8 File 2 message 1
echo Screen message 2
>&9 File 1 message 2
>&8 File 2 message 2
exit /b

Я вирішив використовувати ручки 9 і 8 у зворотному порядку, оскільки таким чином, швидше за все, уникнути можливого постійного перенаправлення через недолік дизайну впровадження перенаправлення Microsoft при виконанні декількох перенаправлень в одній команді. Це малоймовірно, але навіть такий підхід може виявити помилку, якщо ви постараєтеся досить. Якщо ви зробите поетапну переадресацію, ви гарантовано уникнете проблеми.

3>File1.txt ( 4>File2.txt call :sub)
exit /b

:sub
etc.

2
Любіть рішення, де я можу встановити його на залишок файлу
Сем

3
Зверніть увагу , що виклик рішення змінює свої % 0 (до південь в даному випадку) , який може або не може бути те , що ви хочете.
Яннес

1
@Jannes - Правда, але ви завжди можете отримати інформацію про запущений пакетний сценарій, якщо додати модифікатор. Наприклад, %~f0завжди дає повний шлях до пакетного сценарію, навіть коли знаходиться всередині підпрограми CALLED:.
dbenham

3
@ThariqNugrohotomo ->output.txt 2>&1
dbenham

2
@Moondra - це стандартний синтаксис партії для виклику міченої підпрограми в межах одного сценарію. Виконати cmd /?або help cmdз командного рядка консолі для документації. Трюк третього методу полягає в тому, що перенаправлення на CALL застосовується до всіх команд в рамках підпрограми CALLED.
dbenham

66

якщо ви хочете, щоб потоки і помилки перенаправлені

dir >> a.txt 2>&1

27
+1. Також варто зазначити, що використання >>буде додаватися до a.txt. Щоб замість a.txtцього замінити , використовуйте >. stackoverflow.com/q/4458231/1098302
Аарон

Привіт, чи є спосіб перенаправити вихід на консоль?
Сандіп Сінгх

ось що це робить
Kalpesh Soni

16

Я знаю, що це старіший пост, але хтось наткнеться на нього в пошуку Google, і це також виглядає як деякі питання, які ОП задавали в коментарях, спеціально не розглядалися. Крім того, будь ласка, будь ласка, мені, так як це моя перша відповідь, розміщена в ТА. :)

Для перенаправлення виводу на файл, використовуючи динамічно створене ім’я файлу, мій підхід (читання: швидкий і брудний) - це друге рішення, яке пропонує @dbenham. Так, наприклад, це:

@echo off
> filename_prefix-%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log (
echo Your Name Here
echo Beginning Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
REM do some stuff here
echo Your Name Here
echo Ending Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
)

Створиться файл, подібний до того, що ви бачите в цьому скріншоті файлу в цільовому каталозі

Що буде містити цей вихід:

Your Name Here
Beginning Date/Time: 2016-09-16_141048.log
Your Name Here
Ending Date/Time: 2016-09-16_141048.log

Також майте на увазі, що це рішення залежить від локальної локальності, тому будьте уважні, як / коли ви його використовуєте.


Спасибі це було корисно. Швидке запитання: є причина, чому ви використовуєте .log vs .txt? Це має значення?
Мондра

1
@Moondra ні, ні. Це просто семантика в цьому випадку. Це не означає, що не існує додатків, які вимагають / grep на основі типу файлу, тому просто врахуйте, чи / як ваші файли використовуються.
Ентоні

9
echo some output >"your logfile"

або

(
 echo some output
 echo more output
)>"Your logfile"

має заповнити рахунок.

Якщо ви хочете на APPENDвихід, використовуйте >>замість >. >почне новий файл реєстрації.


9
@echo off
>output.txt (
echo Checking your system infor, Please wating...

systeminfo | findstr /c:"Host Name" 
systeminfo | findstr /c:"Domain"

ipconfig /all | find "Physical Address" 

ipconfig | find "IPv4" 
ipconfig | find "Default Gateway"

)

@pause

Я думаю, що це найелегантніший спосіб. Дякую Уеслі!
Kiswanij

5

Існує класна маленька програма, яку ви можете використовувати для перенаправлення виводу на файл і консоль

some_command  ^|  TEE.BAT  [ -a ]  filename 


4

Додайте ці два рядки у верхній частині вашого пакетного файлу, після чого всі stdout та stderr будуть перенаправлені на log.txt:

if not "%1"=="STDOUT_TO_FILE"  %0 STDOUT_TO_FILE %*  >log.txt 2>&1
shift /1

Це працювало для мене, дякую. Якісь особливі міркування, де це може провалитися? (наприклад, переповнення розміру виходу)
CCarlos

Привіт, дякую за вашу відповідь! Чи є спосіб перенаправити його також на консоль?
Сандіп Сінгх

3
@echo OFF
[your command] >> [Your log file name].txt

Я використав команду вище в своєму пакетному файлі, і вона працює. У файлі журналу відображаються результати моєї команди.


0

Це може вийти з ладу у випадку "токсичних" символів на вводі. Зважаючи на такий вхід, як цеIsAnIn ^^^^, це хороший спосіб зрозуміти, що відбувається. Звичайно, є правило, що рядок введення ОБОВ'ЯЗКОВО повинен бути всередині подвійних цитованих знаків, але я маю відчуття, що це правило є дійсним правилом, лише якщо значенням введення є розташування на розділі NTFS (можливо, це правило для URL-адрес I не впевнений). Але це не правило для довільного рядка введення, звичайно (це "хороша практика", але ви не можете з цим порахувати).


0

Додавання наступних рядків у нижній частині пакетного файлу дозволить схопити все так само, як відображено у вікні CMD та експортувати у текстовий файл:

powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^a')
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^c')
powershell Get-Clipboard > MyLog.txt

В основному він виконує функцію виділення всіх -> копіювати в буфер обміну -> вставити у текстовий файл .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.