Отображение вывода командной строки Windows и redirect ее в файл

Как запустить приложение командной строки в командной строке Windows и отобразить и перенаправить вывод в файл одновременно?

Если, например, я должен был запустить команду dir > test.txt , это приведет к перенаправлению вывода в файл с именем test.txt без отображения результатов.

Как написать команду для вывода вывода и перенаправления вывода в файл в командной строке Windows, аналогично команде tee в Unix?

Мне удалось найти решение / обходной путь перенаправления вывода в файл, а затем на консоль:

 dir > a.txt | type a.txt 

где dir – это команда, выход которой нужно перенаправить, a.txt – файл, в котором следует хранить вывод.

Чтобы расширить ответ на davor , вы можете использовать PowerShell следующим образом:

 powershell "dir | tee test.txt" 

Если вы пытаетесь перенаправить вывод exe в текущий каталог, вам нужно использовать .\ On имя файла, например:

 powershell ".\something.exe | tee test.txt" 

Существует Win32-порт команды tee Unix, который делает именно это. См. http://unxutils.sourceforge.net/ или http://getgnuwin32.sourceforge.net/

Проверьте это: wintee

Нет необходимости в cygwin.

Однако я столкнулся и сообщил о некоторых проблемах.

Также вы можете проверить unxutils, потому что он содержит tee (и не нужен cygwin), но будьте осторожны, что выходные EOL являются UNIX-подобными.

И последнее, но не менее важно, если у вас есть PowerShell, вы можете попробовать Tee-Object. Введите get-help tee-object в консоли PowerShell для получения дополнительной информации.

@ tori3852

я нашел это

 dir > a.txt | type a.txt 

не работает (первые несколько строк списка только для геймеров – подозревают какой-то процесс форкирования, а вторая часть, команда «тип» прекращена до того, как завершился тяжелый листинг?), поэтому вместо этого я использовал:

 dir > z.txt && type z.txt 

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

К сожалению, такой вещи нет.

Консольные приложения Windows имеют только один дескриптор вывода. (Ну, есть два STDOUT , STDERR но здесь это неважно) The > перенаправляет вывод, обычно записываемый в дескриптор консоли, в дескриптор файла.

Если вы хотите иметь какое-то мультиплексирование, вам нужно использовать внешнее приложение, на которое вы можете перенаправить вывод. Затем это приложение может снова записать в файл и в консоль.

Простое консольное приложение C # сделало бы трюк:

 using System; using System.Collections.Generic; using System.IO; namespace CopyToFiles { class Program { static void Main(string[] args) { var buffer = new char[100]; var outputs = new List(); foreach (var file in args) outputs.Add(new StreamWriter(file)); outputs.Add(Console.Out); int bytesRead; do { bytesRead = Console.In.ReadBlock(buffer, 0, buffer.Length); outputs.ForEach(o => o.Write(buffer, 0, bytesRead)); } while (bytesRead == buffer.Length); outputs.ForEach(o => o.Close()); } } } 

Чтобы использовать это, вы просто передаете исходную команду в программу и указываете путь к любым файлам, для которых вы хотите дублировать вывод. Например:

 dir | CopyToFiles files1.txt files2.txt 

Будет отображать результаты поиска, а также сохранять результаты в файлах files1.txt и files2.txt.

Обратите внимание, что на пути обработки ошибок не так много (ничего!), И поддержка нескольких файлов может не потребоваться.

Это работает, хотя это немного уродливо:

 dir >_ && type _ && type _ > a.txt 

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

 ECHO Print line to screen and log to file. >_ && type _ && type _ >> logfile.txt 

Да, вы могли бы просто повторить инструкцию ECHO (один раз для экрана и второй раз перенаправляясь на файл журнала), но это выглядит так же плохо, и это проблема обслуживания. По крайней мере, таким образом вам не нужно вносить изменения в сообщения в двух местах.

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

mtee – небольшая утилита, которая очень хорошо работает для этой цели. Это бесплатно, источник открыт, и он просто работает.

Вы можете найти его на http://www.commandline.co.uk .

Используется в пакетном файле для отображения вывода И одновременно создает файл журнала, синтаксис выглядит следующим образом:

  someprocess | mtee /+ mylogfile.txt 

Где / + означает добавление вывода.

Это предполагает, что вы скопировали mtee в папку, которая находится в PATH, конечно.

Я согласен с Брайаном Расмуссеном, порт unxutils – самый простой способ сделать это. В разделе « Пакетные файлы » его страниц Scripting Rob van der Woude предоставляет массу информации об использовании команд MS-DOS и CMD. Я подумал, что у него может быть собственное решение вашей проблемы, и после того, как я начал там копаться, я нашел TEE.BAT , который, кажется, именно так, представляет собой пакетный языковой пакет MS-DOS. Это довольно сложный пакетный файл, и я бы склонен использовать порт unxutils.

Я хотел бы немного рассказать о превосходном ответе Саксон-Друса.

Как указано, вы можете перенаправить вывод исполняемого файла в текущий каталог следующим образом:

 powershell ".\something.exe | tee test.txt" 

Тем не менее, это только logs stdout для test.txt . Это также не журнал stderr .

Очевидным решением было бы использовать что-то вроде этого:

 powershell ".\something.exe 2>&1 | tee test.txt" 

Однако это не будет работать для всех something.exe . Некоторые something.exe s интерпретируют 2>&1 как аргумент и терпят неудачу. Правильное решение состоит в том, чтобы вместо этого были только апострофы вокруг something.exe и это ключи и аргументы, например:

 powershell ".\something.exe --switch1 --switch2 … arg1 arg2 …" 2>&1 | tee test.txt 

Если у вас есть cygwin в вашем пути к среде Windows, вы можете использовать:

  dir > a.txt | tail -f a.txt 

dir 1>a.txt 2>&1 | type a.txt

Это поможет перенаправить как STDOUT, так и STDERR

Я также искал одно и то же решение, после небольшой попытки, я смог успешно выполнить это в командной строке. Вот мое решение:

 @Echo off for /f "Delims=" %%a IN (xyz.bat) do ( %%a > _ && type _ && type _ >> log.txt ) @Echo on 

Он даже захватывает любую команду PAUSE.

отправить вывод на консоль, добавить в консольный журнал, удалить вывод из текущей команды

 dir >> usb-create.1 && type usb-create.1 >> usb-create.log | type usb-create.1 && del usb-create.1 

Вот пример того, что я использовал на основе одного из других ответов

 @echo off REM SOME CODE set __ERROR_LOG=c:\errors.txt REM set __IPADDRESS=xxxx REM Test a variable if not defined __IPADDRESS ( REM Call function with some data and terminate call :TEE %DATE%,%TIME%,IP ADDRESS IS NOT DEFINED goto :EOF ) REM If test happens to be successful, TEE out a message and end script. call :TEE Script Ended Successful goto :EOF REM THE TEE FUNCTION :TEE for /f "tokens=*" %%Z in ("%*") do ( > CON ECHO.%%Z >> "%__ERROR_LOG%" ECHO.%%Z goto :EOF ) 
 @echo on set startDate=%date% set startTime=%time% set /a sth=%startTime:~0,2% set /a stm=1%startTime:~3,2% - 100 set /a sts=1%startTime:~6,2% - 100 fullprocess.bat > C:\LOGS\%startDate%_%sth%.%stm%.%sts%.LOG | fullprocess.bat 

Это создаст файл журнала с текущим временем и временем, и вы можете использовать линии консоли во время процесса

Я знаю, что это очень старая тема, но в предыдущих ответах нет полной реализации Tee в реальном времени, написанной в Batch. Мое решение ниже – гибридный сценарий Batch-JScript, который использует раздел JScript только для получения вывода из команды piped, но обработка данных выполняется в разделе Batch. Преимущество такого подхода состоит в том, что любой программный программист может модифицировать эту программу в соответствии с конкретными потребностями. Эта программа также корректно обрабатывает вывод команды CLS, создаваемой другими пакетными файлами, то есть очищает экран при обнаружении вывода команды CLS.

 @if (@CodeSection == @Batch) @then @echo off setlocal EnableDelayedExpansion rem APATee.bat: Asynchronous (real time) Tee program, Batch-JScript hybrid version rem Antonio Perez Ayala rem The advantage of this program is that the data management is written in Batch code, rem so any Batch programmer may modify it to fit their own needs. rem As an example of this feature, CLS command is correctly managed if "%~1" equ "" ( echo Duplicate the Stdout output of a command in the screen and a disk file echo/ echo anyCommand ^| APATee teeFile.txt [/A] echo/ echo If /A switch is given, anyCommand output is *appended* to teeFile.txt goto :EOF ) if "%2" equ ":TeeProcess" goto TeeProcess rem Get the output of CLS command for /F %%a in ('cls') do set "cls=%%a" rem If /A switch is not provided, delete the file that receives Tee output if /I "%~2" neq "/A" if exist %1 del %1 rem Create the semaphore-signal file and start the asynchronous Tee process echo X > Flag.out if exist Flag.in del Flag.in Cscript //nologo //E:JScript "%~F0" | "%~F0" %1 :TeeProcess del Flag.out goto :EOF :TeeProcess rem Wait for "Data Available" signal if not exist Flag.in goto TeeProcess rem Read the line sent by JScript section set line= set /P line= rem Set "Data Read" acknowledgement ren Flag.in Flag.out rem Check for the standard "End Of piped File" mark if "!line!" equ ":_EOF_:" exit /B rem Correctly manage CLS command if "!line:~0,1!" equ "!cls!" ( cls set "line=!line:~1!" ) rem Duplicate the line in Stdout and the Tee output file echo(!line! echo(!line!>> %1 goto TeeProcess @end // JScript section var fso = new ActiveXObject("Scripting.FileSystemObject"); // Process all lines of Stdin while ( ! WScript.Stdin.AtEndOfStream ) { // Read the next line from Stdin var line = WScript.Stdin.ReadLine(); // Wait for "Data Read" acknowledgement while ( ! fso.FileExists("Flag.out") ) { WScript.Sleep(10); } // Send the line to Batch section WScript.Stdout.WriteLine(line); // Set "Data Available" signal fso.MoveFile("Flag.out", "Flag.in"); } // Wait for last "Data Read" acknowledgement while ( ! fso.FileExists("Flag.out") ) { WScript.Sleep(10); } // Send the standard "End Of piped File" mark WScript.Stdout.WriteLine(":_EOF_:"); fso.MoveFile("Flag.out", "Flag.in"); 

Что-то вроде этого должно делать то, что вам нужно?

 %DATE%_%TIME% > c:\a.txt & type c:\a.txt ipconfig >> c:\a.txt & type c:\a.txt ping localhost >> c:\a.txt & type c:\a.txt pause 

Это вариант предыдущего ответа MTS, однако он добавляет некоторые функции, которые могут быть полезны другим. Вот метод, который я использовал:

  • Команда задается как переменная, которая может использоваться позже в коде, для вывода в командное окно и добавления в файл журнала с использованием set _Temp_Msg_Cmd=
    • команда избегает перенаправления с использованием символа моркови, чтобы команды не оценивались первоначально
  • Временной файл создается с именем файла, аналогичным %~n0_temp.txt пакетному файлу с именем %~n0_temp.txt который использует синтаксис расширения параметра командной строки %~n0 чтобы получить имя командного файла.
  • Результат добавляется в отдельный файл журнала %~n0_log.txt

Вот последовательность команд:

  1. Сообщения вывода и ошибки отправляются во временный файл ^> %~n0_temp.txt 2^>^&1
  2. Содержимое временного файла тогда равно:
    • добавлен в файл журнала ^& type %~n0_temp.txt ^>^> %~n0_log.txt
    • вывод в командное окно ^& type %~n0_temp.txt
  3. Временный файл с сообщением удаляется ^& del /Q /F %~n0_temp.txt

Вот пример:

set _Temp_Msg_Cmd= ^> %~n0_temp.txt 2^>^&1 ^& type %~n0_temp.txt ^>^> %~n0_log.txt ^& type %~n0_temp.txt ^& del /Q /F %~n0_temp.txt

Таким образом, команда может быть просто добавлена ​​после более поздних команд в пакетном файле, который выглядит намного чище:

echo test message %_Temp_Msg_Cmd%

Это может быть добавлено и в конце других команд. Насколько я могу судить, это будет работать, когда сообщения имеют несколько строк. Например, следующая команда выводит две строки, если есть сообщение об ошибке:

net use M: /D /Y %_Temp_Msg_Cmd%

Я использую пакетную подпрограмму с инструкцией «для», чтобы получить команду вывода по одной строке за раз, и оба записывают эту строку в файл и выводят ее на консоль.

 @echo off set logfile=test.log call :ExecuteAndTee dir C:\Program Files Exit /B 0 :ExecuteAndTee setlocal enabledelayedexpansion echo Executing '%*' for /f "delims=" %%a in ('%* 2^>^&1') do (echo.%%a & echo.%%a>>%logfile%) endlocal Exit /B 0 

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

Пример:

 ECHO first line on normal stdout. maybe redirected ECHO second line on normal stdout again. maybe redirected ECHO third line is to ask the user. not redirected >CON ECHO fourth line on normal stdout again. maybe redirected 

Также см. Хорошее описание перенаправления: http://www.p-dd.com/chapter7-page14.html

Как отобразить и перенаправить вывод в файл. Предположим, что если я использую команду dos, dir> test.txt, эта команда перенаправляет вывод в файл test.txt без отображения результатов. как написать команду для вывода вывода и перенаправления вывода в файл с помощью DOS, т. е. командной строки Windows, а не в UNIX / LINUX.

Вы можете найти эти команды в biterscripting ( http://www.biterscripting.com ) полезными.

 var str output lf > $output echo $output # Will show output on screen. echo $output > "test.txt" # Will write output to file test.txt. system start "test.txt" # Will open file test.txt for viewing/editing. 

Это работает в режиме реального времени, но также является довольно уродливым, и производительность медленная. Не хорошо протестированы:

 @echo off cls SET MYCOMMAND=dir /B ECHO File called 'test.bat' > out.txt for /f "usebackq delims=" %%I in (`%MYCOMMAND%`) do ( ECHO %%I ECHO %%I >> out.txt ) pause 

Альтернативой является tee stdout для stderr в вашей программе:

в java:

 System.setOut(new PrintStream(new TeeOutputStream(System.out, System.err))); 

Затем в вашем dos batchfile: java program > log.txt

Stdout перейдет в файл журнала, и stderr (те же данные) отобразятся на консоли.

Так же, как unix

dir | tee a.txt

работает в Windows XP, для этого требуется установка mksnt

Он отображает на promt, а также добавляет к файлу

Я устанавливаю perl на большинстве своих машин, поэтому ответ с помощью perl: tee.pl

 my $file = shift || "tee.dat"; open $output, ">", $file or die "unable to open $file as output: $!"; while() { print $_; print $output $_; } close $output; в my $file = shift || "tee.dat"; open $output, ">", $file or die "unable to open $file as output: $!"; while() { print $_; print $output $_; } close $output; 

dir | perl tee.pl или каталог | perl tee.pl dir.bat

сырой и непроверенный.

  • Пакетные файлы - обработка ошибок
  • Хранить файл внутри пакетного файла?
  • Как заменить подстроки в пакетном файле windows
  • Ошибка пакетного файла Windows. Как может 30000000000000 равняться 40000000000?
  • Проблема с переименованием папок и подпапок с использованием пакетной
  • Как проверить размер файла в пакетном скрипте Windows?
  • Запустить .jar из пакетного файла
  • DOS пакетный цикл FOR с FIND.exe удаляет пустые строки?
  • Как сделать пакетный файл завершенным после возникновения ошибки?
  • Где GOTO: EOF возвращается?
  • Объясните, как работает пакет обновления Windows newline new
  • Давайте будем гением компьютера.