Windows 명령 프롬프트에서 명령 줄 응용 프로그램을 실행하고 출력을 동시에 파일로 표시하고 리디렉션하려면 어떻게해야합니까?
예를 들어, 내가 명령을 실행 하면 결과를 표시하지 않고 dir > test.txt
호출 된 파일로 출력을 리디렉션 test.txt
합니다.
어떻게 명령 출력 표시 쓸 수 및 받는 유사한 프롬프트 Windows 명령의 파일로 리디렉션 출력, tee
유닉스 명령을?
Windows 명령 프롬프트에서 명령 줄 응용 프로그램을 실행하고 출력을 동시에 파일로 표시하고 리디렉션하려면 어떻게해야합니까?
예를 들어, 내가 명령을 실행 하면 결과를 표시하지 않고 dir > test.txt
호출 된 파일로 출력을 리디렉션 test.txt
합니다.
어떻게 명령 출력 표시 쓸 수 및 받는 유사한 프롬프트 Windows 명령의 파일로 리디렉션 출력, tee
유닉스 명령을?
답변:
davor의 답변 을 확장하려면 다음과 같이 PowerShell을 사용할 수 있습니다.
powershell "dir | tee test.txt"
현재 디렉토리에서 exe의 출력을 리디렉션하려는 경우 .\
파일 이름 을 사용해야 합니다. 예 :
powershell ".\something.exe | tee test.txt"
dir
PowerShell의 별칭은에 Get-ChildItem
있는 cmd를의 내부처럼없는 dir
명령. powershell "cmd /c dir | tee test.txt"
cmd 내부 버전을 원하면 필요 합니다
2>&1
예node 2>&1 | tee debug_log.txt
출력을 파일로 리디렉션 한 다음 콘솔 로 리디렉션하는 솔루션 / 해결 방법을 찾을 수있었습니다 .
dir > a.txt | type a.txt
여기서 dir 은 출력을 리디렉션해야하는 명령이고 a.txt 는 출력을 저장할 파일입니다.
&
대신의이 |
같은 일부 명령의 출력에 필요한 ping
또는7z.exe
dir
. 예 : chkdsk /f c: > c:\Temp.txt | c:\Temp.txt
. 다른 프로세스에서 시스템 보고서 파일을 잠갔습니다.
handle output to stderr
- 2>&1
리디렉션을 다음 dir 2>&1 > a.txt & type a.txt
과 같이 추가하십시오 : stderr과 stdout이 혼합되어 있어야합니다 .
Unix tee
명령 의 Win32 포트 가 있습니다. http://unxutils.sourceforge.net/ 또는 http://getgnuwin32.sourceforge.net/을 참조하십시오.
tee
패키지 를 찾기 위해 고생 했다면 gnuwin32.sourceforge.net/packages/coreutils.htm 에서 찾을 수 있습니다 .
이것을 확인하십시오 : wintee
cygwin이 필요 없습니다.
그래도 몇 가지 문제가 발생했습니다.
또한 unxutils 에는 tee가 포함되어 있고 cygwin이 필요하지 않기 때문에 unxutils를 확인할 수 있지만 출력 EOL은 UNIX와 유사합니다.
마지막으로 PowerShell이 있으면 Tee-Object를 사용해 볼 수 있습니다. get-help tee-object
자세한 내용을 보려면 PowerShell 콘솔에 입력 하십시오.
tee
실시간으로 출력합니다. wtee
기능이 동일합니다. 버그를 신경 쓰지 않으면 괜찮습니다.
tori
나는 그것을 발견했다
dir > a.txt | type a.txt
작동하지 않았습니다 (처음 몇 줄의 dir 목록 만-일종의 프로세스 분기점을 의심하고 두 번째 부분은 'type'명령이 무서운 목록이 완료되기 전에 종료 되었습니까?) 대신 대신 사용했습니다.
dir > z.txt && type z.txt
순차적 명령, 하나는 두 번째 시작 전에 완료됩니다.
&
대신 사용해야합니다 . 명령에 어떤 형태의 오류가 있어도 콘솔에서 여전히 로그 파일을 보려고 할 때 유용합니다. 이에 대한 Microsoft의 기사를 참조하십시오 . 그러나이 오류 수준을 0 으로 설정 하는 문제 가 있습니다. &&
type
dir
%errorlevel%
type
불행히도 그런 것은 없습니다.
Windows 콘솔 응용 프로그램에는 단일 출력 핸들 만 있습니다. (음, 두 가지가 있습니다 STDOUT
, STDERR
하지만 여기서 중요하지 않습니다) >
출력은 일반적으로 파일 핸들에 콘솔 핸들에 기록 리디렉션.
어떤 종류의 멀티플렉싱을 원한다면 출력을 전환 할 수있는 외부 응용 프로그램을 사용해야합니다. 그런 다음이 응용 프로그램은 파일과 콘솔에 다시 쓸 수 있습니다.
tee
on * nix는 또한 별도의 응용 프로그램으로 쉘에서 일부 리디렉션이 아닙니다
간단한 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에 모두 저장합니다.
위의 오류 처리 방식이 많지 않으므로 실제로 여러 파일을 지원하지 않아도됩니다.
약간 추한 방법이지만 작동합니다.
dir >_ && type _ && type _ > a.txt
명령문별로 작동하므로 추가하기 위해 사용할 수 있다는 점에서 다른 솔루션보다 약간 더 유연합니다. 메시지를 기록하고 표시하기 위해 배치 파일에서이를 약간 사용합니다.
ECHO Print line to screen and log to file. >_ && type _ && type _ >> logfile.txt
예, ECHO 문 (화면에 한 번, 로그 파일로 두 번째로 리디렉션)을 반복 할 수 있지만, 이는 나쁘게 보이며 약간의 유지 관리 문제입니다. 적어도이 방법으로 두 곳에서 메시지를 변경할 필요는 없습니다.
_은 짧은 파일 이름이므로 배치 파일의 끝에서 배치 파일을 삭제해야합니다 (일괄 파일을 사용하는 경우).
type
(서브 루틴에서) 별도의 줄에 명령을 넣는 것이 고정되었습니다.
mtee는이 목적을 위해 아주 잘 작동하는 작은 유틸리티입니다. 무료이며 소스가 공개되어 있으며 그대로 작동합니다.
http://www.commandline.co.uk 에서 찾을 수 있습니다 . .
배치 파일에서 출력을 표시하고 동시에 로그 파일을 작성하는 데 사용되는 구문은 다음과 같습니다.
someprocess | mtee /+ mylogfile.txt
/ +는 출력을 추가하는 것을 의미합니다.
이것은 물론 경로에있는 폴더에 mtee를 복사했다고 가정합니다.
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
'tee' is not recognized as an internal or external command
명백한 이유가 있습니다. 2>&1
내부 cmd 줄을 사용하면 stderr에 대한 출력으로 인해 powershell에서 오류가 발생합니다.
나는 unxutils 포트가 가장 쉬운 방법 인 Brian Rasmussen에 동의합니다. 그의 스크립팅 페이지 의 배치 파일 섹션에서 Rob van der Woude는 MS-DOS 및 CMD 명령 사용에 대한 풍부한 정보를 제공합니다. 나는 그가 당신의 문제에 대한 네이티브 솔루션을 가지고 있다고 생각하고 거기에서 파고 들자 TEE.BAT를 찾았 습니다 . 이것은 티의 MS-DOS 배치 언어 구현입니다. 꽤 복잡해 보이는 배치 파일이며 내 성향은 여전히 unxutils 포트를 사용하는 것입니다.
나는 이것이 매우 오래된 주제라는 것을 알고 있지만 이전 답변에는 배치로 작성된 실시간 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");
file.exe 2>output.txt
다음은 다른 답변 중 하나를 기반으로 사용한 샘플입니다.
@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
)
이와 같은 것이 필요한 것을해야합니까?
%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
이것은 MTS 의 이전 답변 에 대한 변형 이지만 다른 사람들에게 유용 할 수있는 기능을 추가합니다. 내가 사용한 방법은 다음과 같습니다.
set _Temp_Msg_Cmd=
^
하여 명령이 처음에 평가되지 않음%~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%
@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
현재 날짜 시간과 함께 로그 파일이 생성되며 프로세스 중에 콘솔 라인을 사용할 수 있습니다
"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
%MYCOMMAND%
완료 될 때까지 기다렸다가 많은 경우 실패합니다. 이 라인을 시작으로 빈 줄을 건너 뛰고 ;
같은 콘텐츠와 함께 실패 <space>/<TAB>
, ON
, OFF
또는 /?
. 그러나 나머지는 때때로 작동 할 수 있습니다 :-)
또 다른 변형은 파이프를 분할 한 다음 원하는대로 출력을 재지 정하는 것입니다.
@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
c:\cygwin64\bin\script.exe
하고 입력cmd
하고 입력exit
Cygwin의 cmd.exe를 입력 하고 입력하십시오.exit
Cygwin의 script.exe를 입력 하고 입력하십시오.