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

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

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

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

Ответ 1

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

powershell "dir | tee test.txt"

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

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

Ответ 2

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

dir > a.txt | type a.txt

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

Ответ 4

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

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

Я встречался и сообщал о некоторых проблемах.

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

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

Ответ 5

@tori3852

я нашел это

dir > a.txt | type a.txt

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

dir > z.txt && type z.txt

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

Ответ 6

Простая консольная консоль С# сделала бы трюк:

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<TextWriter>();

            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.

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

Ответ 7

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

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

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

Ответ 8

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

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

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

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

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

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

Ответ 9

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

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

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

    someprocess | mtee /+ mylogfile.txt

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

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

Ответ 10

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

Ответ 11

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

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

Ответ 12

Я хотел бы немного подробнее рассказать о саксонских друзах отличный ответ.

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

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

Однако, это только регистрирует stdout в test.txt. Он также не регистрирует stderr.

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

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

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

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

Ответ 13

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

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

Ответ 14

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

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

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

Ответ 15

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

@echo off
REM SOME CODE
set __ERROR_LOG=c:\errors.txt
REM set __IPADDRESS=x.x.x.x

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
)

Ответ 16

Я знаю, что это очень старая тема, но в предыдущих ответах нет полной реализации Tee в реальном времени, написанной в Batch. Мое решение ниже - гибрид Batch-JScript script, который использует раздел 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");

Ответ 17

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

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

Ответ 18

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

%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

Ответ 19

@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

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

Ответ 20

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

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

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

  • Сообщения о выходе и ошибке отправляются во временный файл ^> %~n0_temp.txt 2^>^&1
  • Содержимое временного файла тогда равно:
    • прилагается к файлу журнала ^& type %~n0_temp.txt ^>^> %~n0_log.txt
    • вывод в окно команд ^& type %~n0_temp.txt
  • Временный файл с сообщением удаляется ^& 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%

Ответ 21

Так же, как Unix.

dir | tee a.txt

mksnt ли на Windows XP, требует установленного mksnt.

Он отображается в приглашении, а также добавляется в файл.

Ответ 22

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

@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

Ответ 23

Если вы находитесь в CLI, почему бы не использовать цикл FOR, чтобы "делать" все, что вы хотите:

for /F "delims=" %a in ('dir') do @echo %a && echo %a >> output.txt

Отличный ресурс по Windows CMD для циклов: https://ss64.com/nt/for_cmd.html Ключом здесь является установка разделителей (разделителей), которые будут разбивать каждую строку вывода, на ноль. Таким образом, он не будет нарушен по умолчанию пустого пространства. % A - это произвольная буква, но она используется в разделе "do", чтобы... ну что-то делать с символами, которые были проанализированы в каждой строке. В этом случае мы можем использовать амперсанды (&&) для выполнения 2-й команды echo для создания или добавления (>>) к файлу по нашему выбору. Безопаснее придерживаться этого порядка команд DO в случае, если при записи файла возникнут проблемы, мы сначала по крайней мере выведем эхо на консоль. Знак (@) перед первым эхо-сигналом подавляет консоль от показа самой эхо-команды и вместо этого просто отображает результат команды, которая должна отображать символы в% a. В противном случае вы увидите:

Громкость эха в диске [x] Windows
Том на диске [x] - Windows

UPDATE: /F пропускает пустые строки, и единственное, что нужно исправить, - это предварительно отфильтровать вывод, добавив символ в каждую строку (возможно, с номерами строк через команду find). Решение этого в CLI не быстро и не красиво. Кроме того, я не включил STDERR, поэтому здесь также фиксируются ошибки:

for /F "delims=" %a in ('dir 2^>^&1') do @echo %a & echo %a >> output.txt

Перенаправление сообщений об ошибках

Символы (^) предназначены для того, чтобы экранировать символы после них, потому что команда представляет собой строку, которая интерпретируется, а не вводится непосредственно в командной строке.

Ответ 24

Следующее помогает, если вы хотите что-то действительно увидеть на экране - даже если пакетный файл был перенаправлен в файл. Устройство 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

Ответ 25

Как отображать и перенаправлять вывод в файл. Предположим, что если я использую dos command, 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.

Ответ 26

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

@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

Ответ 27

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

в java:

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

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

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

Ответ 28

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

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

dir | perl tee.pl или dir | perl tee.pl dir.bat

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

Ответ 29

PowerShell "dir | tee test.txt" работал для меня. Спасибо

Ответ 30

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

    @echo off
    for /f "tokens=1,* delims=:" %%P in ('findstr /n "^"') do (
      echo.%%Q
      echo.%%Q>&3
    )
    @exit/b %errorlevel%

Сохраните вышеперечисленное в файл .bat. Он также разделяет вывод текста в файловом потоке 1 на файловый поток 3, который вы можете перенаправить по мере необходимости. В приведенных ниже примерах я вызывал приведенный выше скрипт splitPipe.bat...

    dir | splitPipe.bat  1>con  2>&1  3>my_stdout.log

    splitPipe.bat 2>nul < somefile.txt