Перенаправление вывода из пакетного файла

110

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

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

Имейте в виду, что я не хочу запускать пакет из cmd, а затем перенаправлять вывод; Я хочу перенаправить вывод из пакета, если это возможно.

user3085030
источник

Ответы:

161

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

@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.
Dbenham
источник
2
Мне нравятся решения, в которых я могу установить его для оставшейся части файла
Сэм
3
Обратите внимание, что решение вызова изменяет ваш % 0 ( в данном случае на sub ), что может быть или не быть тем, что вы хотите.
Jannes
2
@Jannes - Верно, но вы всегда можете получить информацию о запущенном пакетном скрипте, если добавите модификатор. Например, %~f0всегда дает полный путь к пакетному сценарию, даже если находится внутри подпрограммы CALLed :.
dbenham 07
3
@ThariqNugrohotomo ->output.txt 2>&1
dbenham
2
@Moondra - это стандартный пакетный синтаксис для вызова помеченной подпрограммы в том же скрипте. Выполните cmd /?или help cmdиз командной строки консоли для документации. Уловка третьего метода заключается в том, что перенаправление на CALL применяется ко всем командам в подпрограмме CALLed.
dbenham
66

если вы хотите перенаправлять как исходящие, так и ошибочные потоки

dir >> a.txt 2>&1
Кальпеш Сони
источник
27
+1. Также стоит отметить, что using >>будет добавляться в a.txt. a.txtВместо этого для перезаписи используйте >. stackoverflow.com/q/4458231/1098302
Аарон
Привет, есть ли способ перенаправить вывод на консоль?
Сандип Сингх,
вот что он делает
Калпеш Сони
16

Я знаю, что это более старый пост, но кто-то наткнется на него в поиске Google, и также похоже, что некоторые вопросы, заданные OP в комментариях, не были конкретно рассмотрены. Кроме того, будьте осторожны со мной, так как это мой первый ответ, опубликованный на SO. :)

Чтобы перенаправить вывод в файл с использованием динамически сгенерированного имени файла, мой подход (читай: быстро и грязно) - это второе решение, предлагаемое @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 против .txt? Это имеет значение?
Moondra
1
@Moondra, нет. В данном случае это просто семантика. Это не значит, что нет приложений, которые требуют / grep в зависимости от типа файла, поэтому просто знайте, используются ли ваши файлы и как они это делают.
Энтони
9
echo some output >"your logfile"

или

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

должен заполнить счет.

Если вы хотите получить APPENDрезультат, используйте >>вместо >. >запустит новый файл журнала.

Magoo
источник
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 

AquaAlex
источник
4

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

if not "%1"=="STDOUT_TO_FILE"  %0 STDOUT_TO_FILE %*  >log.txt 2>&1
shift /1
Ilgitano
источник
Это сработало для меня, спасибо. Есть ли какие-либо особые соображения, когда это может потерпеть неудачу? (например, переполнение размера вывода)
CCarlos
Привет, спасибо за ответ! есть ли способ перенаправить его и на консоль?
Сандип Сингх
3
@echo OFF
[your command] >> [Your log file name].txt

Я использовал приведенную выше команду в своем командном файле, и она работает. В файле журнала он показывает результаты моей команды.

Индра Пермана
источник
0

Это может не сработать в случае "токсичных" символов во вводе. Рассмотрение ввода, подобного этому, IsAnIn ^^^^ put - хороший способ понять, что происходит. Конечно, существует правило, согласно которому входная строка ДОЛЖНА быть внутри двойных кавычек, но я чувствую, что это правило является действительным правилом только в том случае, если значение входных данных находится в разделе NTFS (возможно, это правило для URL-адресов, которые я Я не уверен). Но это, конечно, не правило для произвольной входной строки (это «хорошая практика», но вы не можете рассчитывать по ней).

Ян Антонин
источник
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

Он в основном выполняет выделение всего -> копирование в буфер обмена -> вставку в текстовый файл .

GioVi
источник