development

Windows 명령 프롬프트 출력 표시 및 파일로 리디렉션

big-blog 2020. 3. 1. 15:56
반응형

Windows 명령 프롬프트 출력 표시 및 파일로 리디렉션


Windows 명령 프롬프트에서 명령 줄 응용 프로그램을 실행하고 출력을 동시에 파일로 표시하고 리디렉션하려면 어떻게해야합니까?

예를 들어, 내가 명령을 실행 하면 결과를 표시하지 않고 dir > test.txt호출 된 파일로 출력을 리디렉션 test.txt합니다.

어떻게 명령 출력 표시 쓸 수 받는 유사한 프롬프트 Windows 명령의 파일로 리디렉션 출력, tee유닉스 명령을?


davor의 답변 을 확장하려면 다음과 같이 PowerShell을 사용할 수 있습니다.

powershell "dir | tee test.txt"

현재 디렉토리에서 exe의 출력을 리디렉션하려는 경우 .\파일 이름 을 사용해야 합니다. 예 :

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

출력을 파일로 리디렉션 한 다음 콘솔 로 리디렉션하는 솔루션 / 해결 방법을 찾을 수있었습니다 .

dir > a.txt | type a.txt

여기서 dir 은 출력을 리디렉션해야하는 명령이고 a.txt 는 출력을 저장할 파일입니다.


Unix tee명령 의 Win32 포트 가 있습니다. http://unxutils.sourceforge.net/ 또는 http://getgnuwin32.sourceforge.net/을 참조하십시오.


이것을 확인하십시오 : wintee

cygwin이 필요 없습니다.

그래도 몇 가지 문제가 발생했습니다.

또한 unxutils 에는 tee가 포함되어 있고 cygwin이 필요하지 않기 때문에 unxutils를 확인할 수 있지만 출력 EOL이 UNIX와 비슷하다는 점에 유의하십시오.

마지막으로 PowerShell이 ​​있으면 Tee-Object를 사용해 볼 수 있습니다. get-help tee-object자세한 내용을 보려면 PowerShell 콘솔에 입력 하십시오.


tori

나는 그것을 발견했다

dir > a.txt | type a.txt

작동하지 않았습니다 (처음 몇 줄의 dir 목록 만-일종의 프로세스 분기점을 의심하고 두 번째 부분은 'type'명령이 무서운 목록이 완료되기 전에 종료 되었습니까?). 대신 대신 사용했습니다.

dir > z.txt && type z.txt

순차적 명령, 하나는 두 번째 시작 전에 완료됩니다.


간단한 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<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 

dir의 결과를 표시하고 결과를 files1.txt와 files2.txt에 모두 저장합니다.

위의 오류 처리 방식이 많지 않으므로 실제로 여러 파일을 지원하지 않아도됩니다.


불행히도 그런 것은 없습니다.

Windows 콘솔 응용 프로그램에는 단일 출력 핸들 만 있습니다. (음, 두 가지가 있습니다 STDOUT, STDERR하지만 여기서 중요하지 않습니다) >출력은 일반적으로 파일 핸들에 콘솔 핸들에 기록 리디렉션.

어떤 종류의 멀티플렉싱을 원한다면 출력을 전환 할 수있는 외부 응용 프로그램을 사용해야합니다. 이 응용 프로그램은 파일과 콘솔에 다시 쓸 수 있습니다.


약간 추한 방법이지만 작동합니다.

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를 복사했다고 가정합니다.


나는 unxutils 포트가 가장 쉬운 방법 인 Brian Rasmussen에 동의합니다. 그의 스크립팅 페이지배치 파일 섹션에서 Rob van der Woude는 MS-DOS 및 CMD 명령 사용에 대한 풍부한 정보를 제공합니다. 나는 그가 당신의 문제에 대한 네이티브 솔루션을 가지고 있다고 생각하고 거기에서 파고 들자 TEE.BAT를 찾았 습니다 . 이것은 티의 MS-DOS 배치 언어 구현입니다. 꽤 복잡해 보이는 배치 파일이며 내 성향은 여전히 ​​unxutils 포트를 사용하는 것입니다.


Windows 환경 경로에 cygwin이 있으면 다음을 사용할 수 있습니다.

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

Saxon Druce의 훌륭한 답변을 조금 확장하고 싶습니다 .

언급했듯이 다음과 같이 현재 디렉토리에서 실행 파일의 출력을 리디렉션 할 수 있습니다.

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

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 명령도 캡처합니다.


다음은 다른 답변 중 하나를 기반으로 사용한 샘플입니다.

@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
)

나는 이것이 매우 오래된 주제라는 것을 알고 있지만 이전 답변에는 배치로 작성된 실시간 Tee의 완전한 구현이 없습니다. 아래의 솔루션은 파이프 스크립트 명령에서 출력을 얻기 위해 JScript 섹션을 사용하는 Batch-JScript 하이브리드 스크립트이지만 데이터 처리는 Batch 섹션에서 수행됩니다. 이 방법은 모든 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

콘솔에 출력 보내기, 콘솔 로그에 추가, 현재 명령에서 출력 삭제

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

@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

현재 날짜 시간과 함께 로그 파일이 생성되며 프로세스 중에 콘솔 라인을 사용할 수 있습니다


이것은 MTS 의 이전 답변대한 변형 이지만 다른 사람들에게 유용 할 수있는 기능을 추가합니다. 내가 사용한 방법은 다음과 같습니다.

  • 명령은 다음 코드를 사용하여 명령 창에 출력하고 로그 파일에 추가하기 위해 코드 전체에서 나중에 사용할 수있는 변수로 설정됩니다. set _Temp_Msg_Cmd=
    • 명령이 당근 문자를 사용하여 리디렉션이스케이프 ^하여 명령이 처음에 평가되지 않음
  • 명령 행 매개 변수 확장 구문%~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%


"for"문과 함께 배치 서브 루틴을 사용하여 한 번에 한 줄씩 명령 출력을 얻고 해당 줄을 파일에 쓰고 콘솔에 출력합니다.

@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

CLI를 사용하는 경우 FOR 루프를 사용하여 원하는 것을 "DO"하지 마십시오.

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

루프 용 Windows CMD에 대한 훌륭한 리소스 : https://ss64.com/nt/for_cmd.html여기서 핵심은 각 출력 라인을 분리 할 수있는 델리 미터 (델리)를 설정하는 것입니다. 이렇게하면 기본 공백이 깨지지 않습니다. % a는 임의의 문자이지만 "do"섹션에서 각 행에서 구문 분석 된 문자로 무언가를 수행하는 데 사용됩니다. 이 경우 앰퍼샌드 (&&)를 사용하여 두 번째 echo 명령을 실행하여 선택한 파일에 생성 또는 추가 (>>) 할 수 있습니다. 파일을 쓰는 데 문제가있는 경우이 순서의 DO 명령을 유지하는 것이 더 안전합니다. 최소한 에코를 콘솔에 먼저 가져옵니다. 첫 번째 반향 앞의 at 기호 (@)는 콘솔에서 반향 명령 자체를 표시하지 않고 대신 문자를 % a로 표시하는 명령의 결과 만 표시합니다. 그렇지 않으면 다음과 같이 표시됩니다.

드라이브 [x]의 에코 볼륨이 Windows입니다. 드라이브 [x]의 에코 볼륨
이 Windows입니다.

업데이트 : / F는 빈 줄을 건너 뛰고 수정은 모든 줄에 문자를 추가하여 출력을 사전 필터링하는 것입니다 (find 명령을 통해 줄 번호로 가능). CLI에서 이것을 해결하는 것은 빠르거나 예쁘지 않습니다. 또한 STDERR을 포함하지 않았으므로 여기에 캡처 오류도 있습니다.

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

오류 메시지 리디렉션

캐럿 (^)은 명령 뒤에 직접 입력하는 것과 달리 해석되는 문자열이므로 명령 뒤에 기호를 이스케이프 처리해야합니다.


유닉스처럼.

dir | tee a.txt

Windows XP에서는 작동해야합니다 mksnt.

프롬프트에 표시되고 파일에 추가됩니다.


배치 파일이 파일로 리디렉션 된 경우에도 실제로 화면에 표시되는 것을 원하는 경우에 도움이됩니다. 장치 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를 사용하여 출력을 표시하고 출력을 파일로 리디렉션하는 명령을 작성하는 방법 (예 : UNIX / LINUX가 아닌 Windows 명령 프롬프트)

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

대안은 프로그램 내에서 stdout을 stderr에 연결하는 것입니다.

자바에서 :

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

그런 다음 dos 배치 파일에서 : java program > log.txt

stdout은 로그 파일로 이동하고 stderr (동일한 데이터)가 콘솔에 표시됩니다.


나는 대부분의 컴퓨터에 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 | 펄 티 .pl dir.bat

조잡하고 테스트되지 않은.


또 다른 변형은 파이프를 분할 한 다음 원하는대로 출력을 재지 정하는 것입니다.

    @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

이것을 시도하십시오 :
dir> test.txt & type test.txt

참고 URL : https://stackoverflow.com/questions/796476/displaying-windows-command-prompt-output-and-redirecting-it-to-a-file



반응형