bat 스크립트로 콘솔 출력을 파일로 에코하고 보내려면 어떻게합니까?


136

작업을 실행하고 출력을 텍스트 파일로 보내는 배치 스크립트가 있습니다. 콘솔 창에 출력을 표시하는 방법이 있습니까?

예를 들어 :

c:\Windows>dir > windows-dir.txt

dir콘솔 창 에 표시하고 텍스트 파일로 출력하는 방법이 있습니까?


여기 에 당신이 할 수있는 리디렉션과 몇 가지 예가 설명되어 있습니다. <br> 도움이
되길 바랍니다


@Vadzim, 2009 년 2 월 2 일 16:38에 질문 한 질문은 거의 3 개월 후 2009 년 4 월 28 일 06:32에 질문을 복제 한 것으로 간주 할 수 없습니다.
Compo

답변:


216

아니요, 순수한 리디렉션을 사용할 수 없습니다.
그러나 tee.bat 와 같은 몇 가지 트릭으로 할 수 있습니다.

나는 리디렉션을 조금 설명하려고합니다.

> file 또는 <file 을 사용하여 10 개의 스트림 중 하나를 리디렉션
합니다. 리디렉션이 명령 전후에있는 경우 중요하지 않으므로이 두 줄은 거의 동일합니다.

dir > file.txt
> file.txt dir

이 예제에서 리디렉션은 1> 의 바로 가기 일 뿐이 므로 스트림 1 (STDOUT)이 리디렉션됩니다.
따라서 2> err.txt 와 같이 숫자를 앞에 추가하여 모든 스트림을 리디렉션 할 수 있으며 한 줄로 여러 스트림을 리디렉션 할 수도 있습니다.

dir 1> files.txt 2> err.txt 3> nothing.txt

이 예제에서 "표준 출력"은 files.txt에 들어가고 모든 오류는 err.txt에 있으며 stream3은 nothing.txt에 들어갑니다 (DIR은 스트림 3을 사용하지 않습니다).
Stream0은 STDIN입니다.
Stream1은 STDOUT
입니다.
Stream2 는 STDERR입니다. Stream3-9는 사용되지 않습니다.

그러나 동일한 스트림을 여러 번 리디렉션하려고하면 어떻게됩니까?

dir > files.txt > two.txt

"하나만있을 수 있습니다"그리고 그것은 항상 마지막 것입니다!
따라서 dir> two.txt와 같습니다.

좋아, 스트림을 다른 스트림으로 리디렉션하는 또 다른 가능성이 있습니다.

dir 1>files.txt 2>&1 

2> & 1 리디렉션 stream2 스트림 1 행 및 1> files.txt 리디렉션 모든 files.txt .
순서는 여기서 중요합니다!

dir ... 1>nul 2>&1
dir ... 2>&1 1>nul

다르다. 첫 번째는 모두 (STDOUT 및 STDERR)를 NUL로
리디렉션하지만 두 번째 행은 STDOUT을 NUL로, STDERR을 "빈"STDOUT으로 리디렉션합니다.

한 가지 결론으로, Otávio Décio와 andynormancx의 예제가 작동하지 않는 이유는 분명합니다.

command > file >&1
dir > file.txt >&2

둘 다 stream1을 두 번 리디렉션하려고하지만 "하나만있을 수 있습니다"는 항상 마지막 것입니다.
그래서 당신은 얻을

command 1>&1
dir 1>&2

그리고 첫 번째 샘플에서 stream1을 stream1로 리디렉션하는 것은 허용되지 않습니다 (매우 유용하지는 않습니다).

도움이 되길 바랍니다.


24
따라서 네이티브 윈도우 쉘에서는 불가능합니다.
fantastory

7
@fantastory 가능하다면, dbenham Windows 배치
jeb

97
나는 단지이 전체 게시물을 읽고 모든 것이 "아니오"로 요약 될 수 있다는 것을 알 수 없다.
Charles McKelvey

1
두 번째 메커니즘 인 "핸들 복제"는 어떻습니까? 3<&2(GT 대신 LT 참고) 실험 한 다음 3>errors.txt. 그러나 이것은 잘못되었습니다-모든 후속 stderr 출력이 캡처되었습니다 errors.txt(즉, 다른 명령에서도)!
Tomasz Gandor

for /f "delims=" %%v in ('dir') do echo %%v>>file.txt그래도 사용할 수 있습니다 .
scriptmastere02

32

다음 과 같은 방식으로 Windows 버전의 UNIX tee 명령 ( http://unxutils.sourceforge.net 에서 찾음 )을 사용하십시오.

mycommand > tee outpu_file.txt

STDERR 출력도 필요한 경우 다음을 사용하십시오.
2>&1STDOUT에 STDERR 출력 (기본 스트림)을 결합한다.

mycommand 2>&1 | tee output_file.txt

3
PowerShell을 티 - 개체 제공 유사한 기능을 제공합니다. Get-Process | Tee-Object -file c : \ scripts \ test.txt
Kevin Obee

나는 powershell과 일반 쉘 모두에서 이것을 시도했다. 명령 을 호출하는 대신 1>tee a.txtstdout을 이름이 지정된 파일로 리디렉션 tee합니다 tee. 누구든지이 답변이 효과가 있는지 확인할 수 있습니까?
mafu

@mafu 나는 이것을 확인할 수 있습니다.
Cerno

@mafu 위의 답변은 약간 정확하지 않습니다. 파이프 "|"를 사용해야합니다 상단 예에서 ">"대신. 이상하게도, STDOUT 및 STDERR 출력의 순서는이 경우 명령 행에서 혼합되었습니다. 하단 예제는 완벽하게 작동합니다.
Cerno

또한 sourceforge 다운로드가 중단되었습니다. 여기 다른 호스트를 발견 wzw.tum.de/public-html/syring/win32/UnxUtilsDist.html (뮌헨 대학)
Cerno

9

실시간으로 출력이 필요하지 않은 경우 (즉, 프로그램이 출력하는 동안) 추가 할 수 있습니다

type windows-dir.txt

그 줄 후에.


또는 같은 줄에 (프롬프트에서 유용함) : dir > windows-dir.txt & type windows-dir.txt. 이것은 다음 블록에도 적용됩니다 ( echo %date% <NL> echo %username% <NL> echo %time% <NL> pause>CON )>test.txt & type test.txt.. 그러나 실시간으로 출력이 필요한 경우이를 위해 툴 의 Windows 포트를 사용할 수 있습니다 .
mousio


6

예, 콘솔 (화면)과 파일에 단일 명령 출력을 표시하는 방법이 있습니다. 귀하의 예를 사용하여 ...

@ECHO OFF
FOR /F "tokens=*" %%I IN ('DIR') DO ECHO %%I & ECHO %%I>>windows-dir.txt

상해:

FOR명령은 명령 또는 텍스트의 출력을 변수로 구문 분석하며 여러 번 참조 할 수 있습니다.

와 같은 명령의 경우 DIR /B아래 예와 같이 작은 따옴표로 묶습니다. DIR /B원하는 명령으로 텍스트를 바꾸십시오 .

FOR /F "tokens=*" %%I IN ('DIR /B') DO ECHO %%I & ECHO %%I>>FILE.TXT

텍스트를 표시하려면 아래 예와 같이 텍스트를 큰 따옴표로 묶으십시오.

FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO ECHO %%I & ECHO %%I>>FILE.TXT

... 그리고 줄 바꿈으로 ...

FOR /F "tokens=*" %%I IN ("Find this text on console (screen) and in file") DO (
  ECHO %%I & ECHO %%I>>FILE.TXT
)

콘솔 (화면)에서만 출력을 원하고 다른 시간은 파일로만 보내고 다른 시간은 둘 다로 보내려면 시간이 아래에 표시된대로 변수를 사용하여 FOR 루프의 "DO"절을 지정하십시오 %TOECHOWHERE%.

@ECHO OFF
FOR %%I IN (TRUE FALSE) DO (
  FOR %%J IN (TRUE FALSE) DO (
    SET TOSCREEN=%%I & SET TOFILE=%%J & CALL :Runit)
)
GOTO :Finish

:Runit
  REM Both TOSCREEN and TOFILE get assigned a trailing space in the FOR loops
  REM above when the FOR loops are evaluating the first item in the list,
  REM "TRUE".  So, the first value of TOSCREEN is "TRUE " (with a trailing
  REM space), the second value is "FALSE" (no trailing or leading space).
  REM Adding the ": =" text after "TOSCREEN" tells the command processor to
  REM remove all spaces from the value in the "TOSCREEN" variable.
  IF "%TOSCREEN: =%"=="TRUE" (
      IF "%TOFILE: =%"=="TRUE" (
          SET TEXT=On screen, and in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I & ECHO %%I>>FILE.TXT"
        ) ELSE (
          SET TEXT=On screen, not in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I"
      )
    ) ELSE (
      IF "%TOFILE: =%"=="TRUE" (
          SET TEXT=Not on screen, but in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I>>FILE.txt"
        ) ELSE (
          SET TEXT=Not on screen, nor in "FILE.TXT"
          SET TOECHOWHERE="ECHO %%I>NUL"
      )
  )
  FOR /F "tokens=*" %%I IN ("%TEXT%") DO %TOECHOWHERE:~1,-1%
GOTO :eof

:Finish
  ECHO Finished [this text to console (screen) only].
  PAUSE

delims=대신 사용해야 합니다.
scriptmastere02

3
command > file >&1

버퍼를 쓰레기로 채우지 않고 배치 작업을 실행할 수 있기 때문에 화면에 데이터를 쓰지 않을 때 더 빠릅니다. 디버깅하는 경우> 파일 구문을 사용하지 않습니다.
랜덤 개발자

@andynormancx yup는 CMD에서 잘라내어 붙여 넣는 대신 입력하는 것을 잊었습니다.
랜덤 개발자

Windows 명령 프롬프트에서 구문이 작동하지 않고 대신 type 명령을 사용했습니다.
JamesEggers

& 2가 작동하지만 테스트 할 때 파일이 작성되지 않습니다.
JamesEggers

5
"dir> file.txt> & 2"를 수행하면 file.txt가 생성되지 않습니다. 콘솔에서 디렉토리의 출력이 에코되지만 파일이 작성되지 않습니다. "> & 2"가 없으면 파일이 작성됩니다.
JamesEggers

2

출력 파일을 바꾸지 않고 추가하려는 경우 사용할 수 있습니다

dir 1>> files.txt 2>> err.txt

또는

dir 1>> files.txt 2>>&1

2

내 선택은 이것이었다 :

메시지를 수신하고 콘솔과 로그 파일로 전송하는 프로세스를 자동화하는 서브 루틴을 작성하십시오.

setlocal
set logfile=logfile.log

call :screenandlog "%DATE% %TIME% This message goes to the screen and to the log"    

goto :eof

:screenandlog
set message=%~1
echo %message% & echo %message% >> %logfile%
exit /b

메시지에 변수를 추가하는 경우 서브 루틴으로 보내기 전에 따옴표를 제거해야합니다. 그렇지 않으면 배치를 망칠 수 있습니다. 물론 이것은 에코에만 적용됩니다.


그렇습니다! 나는 이것을 정말로 좋아한다!! 그래도 세 가지를 변경했습니다. 1) 나는 setlocal enabledelayedexpansion단지 setlocal 2 대신에 사용한다. 나는 서브 루틴 내에서 >> !logfile!대신 로그 파일 변수에 지연 확장을 사용한다 >> %logfile%. 이런 식으로 코드 블록 내에서 호출 될 때 (if 문 내에서와 같이) 작동합니다. 3) 추가 변수가 필요하지 않기 때문에 "메시지 설정"줄을 제거했습니다. 우리는 이미 그것을 가지고 $~1있으므로 echo $~1두 echo 명령 모두 가지고 있습니다 .
Nate

2

cmd 화면과 log 모두에 대한 실시간 출력을 처리 할 수있는 간단한 C # 콘솔을 만들었습니다.

class Tee
{
    static int Main(string[] args)
    {
        try
        {
            string logFilePath = Path.GetFullPath(args[0]);

            using (StreamWriter writer = new StreamWriter(logFilePath, true))
            {
                for (int value; (value = Console.In.Read()) != -1;)
                {
                    var word = Char.ConvertFromUtf32(value);
                    Console.Write(word);
                    writer.Write(word);
                }
            }
        }
        catch (Exception)
        {
            return 1;
        }
        return 0;
    }
}

배치 파일 사용법은 Unix를 사용하는 방법과 동일합니다 tee

foo | tee xxx.log

https://github.com/iamshiao/Tee 를 컴파일하는 도구가없는 경우 Tee.exe가 포함 된 저장소가 있습니다.



0

"Tomas R"에서 제공하는 솔루션은 OP의 질문에 완벽하게 작동하며 기본적으로 사용 가능합니다.

시도 : chkdsk c :> output.txt | output.txt 유형

이 명령의 출력은 파일에 직렬로 출력되는 완료 백분율을 포함하므로 약간 지저분하게 보입니다 (예 : 텍스트가 진행됨에 따라 추가됨). 이것은 STDOUT (화면)으로 출력되는 비트에는 발생하지 않습니다. 리디렉션없이 동일한 명령을 수행하는 경우와 같은 방법입니다.


-3

나는 당신이 이것의 라인을 따라 무언가를 원한다고 생각합니다.

echo Your Msg> YourTxtFile.txt

또는 새로운 줄을 원한다면 :

echo Your Msg>> YourTxtFile.txt

이 명령은 로그에 유용합니다.

참고 : 때때로 컴퓨터의 전체 텍스트 파일이 고장 나고 교체됩니다.

다른 참고 사항 : 파일이 존재하지 않으면 파일이 생성됩니다.


1
아니요, OP는 파일 화면 으로 출력하기를 원했습니다 . 당신은 단지 파일에 씁니다. (그리고 >있다 디자인 파일을 덮어 쓸가. >>추가 )
스테판
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.