Windowsコマンドプロンプトでコマンドラインアプリケーションを実行し、出力を表示すると同時にファイルにリダイレクトするにはどうすればよいですか?
たとえば、コマンドを実行すると、結果が表示さdir > test.txt
れtest.txt
ずに、呼び出されたファイルに出力がリダイレクトされます。
UNIX のコマンドと同様に、Windowsコマンドプロンプトで出力を表示し、出力をファイルにリダイレクトするコマンドをどのように記述できますtee
か?
Windowsコマンドプロンプトでコマンドラインアプリケーションを実行し、出力を表示すると同時にファイルにリダイレクトするにはどうすればよいですか?
たとえば、コマンドを実行すると、結果が表示さdir > test.txt
れtest.txt
ずに、呼び出されたファイルに出力がリダイレクトされます。
UNIX のコマンドと同様に、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は出力を保存するファイルです。
&
、aではなくa |
が必要であることがわかりましたping
7z.exe
dir
。例:chkdsk /f c: > c:\Temp.txt | c:\Temp.txt
。システムレポートファイルが別のプロセスによってロックされています。
handle output to stderr
- 2>&1
リダイレクトを次のように追加します。stderr とstdoutを混在させる必要がdir 2>&1 > a.txt & type a.txt
あります。
Unix tee
コマンドのWin32ポートがあり、まさにそれを行います。参照してくださいhttp://unxutils.sourceforge.net/またはhttp://getgnuwin32.sourceforge.net/
tee
パッケージを見つけるのに苦労した場合、それはgnuwin32.sourceforge.net/packages/coreutils.htmにあります。
これをチェックしてください:wintee
cygwinは必要ありません。
私はいくつかの問題に遭遇して報告しました。
また、teeが含まれている(そしてcygwinは不要)ので、unxutilsを確認することもできますが、ここでは出力EOLがUNIXに似ていることに注意してください。
最後に、重要なことですが、PowerShellがある場合は、Tee-Objectを試すことができます。get-help tee-object
詳細については、PowerShellコンソールに入力してください。
tee
リアルタイムで出力します。wtee
同じ機能を持っています。バグを気にしないのであれば、それで十分です。
あずきっく
見つけた
dir > a.txt | type a.txt
動作しませんでした(dirリストの最初の数行のみ-何らかのプロセスの分岐が疑われ、2番目の部分、 'type'コマンドはdireリストが完了する前に終了しましたか?)。
dir > z.txt && type z.txt
実行したコマンド-順次コマンド。2番目のコマンドが開始する前に完了します。
&
代わりに使用してください。これは、コマンドになんらかの形式のエラーがあり、コンソールにログファイルを表示したい場合に役立ちます。これに関するマイクロソフトの記事を参照してください。ただし、これにはエラーレベル(0になる)に設定されるという問題があります。&&
type
dir
%errorlevel%
type
残念ながらそのようなことはありません。
Windowsコンソールアプリケーションには、単一の出力ハンドルしかありません。(まあ、2つありますが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ステートメントを繰り返し(画面に1回、ログファイルに2回リダイレクト)することもできますが、見た目も悪く、メンテナンスの問題でもあります。少なくともこの方法では、2つの場所でメッセージを変更する必要はありません。
_は短いファイル名なので、バッチファイルの最後で削除する必要があります(バッチファイルを使用している場合)。
type
ただし、コマンドを(サブルーチン内の)別の行に置くことで修正されました。
mteeは、この目的に非常によく機能する小さなユーティリティです。それは無料であり、ソースはオープンであり、それはちょうどうまくいきます。
http://www.commandline.co.ukで見つけることができ ます。
バッチファイルで使用して出力を表示し、同時にログファイルを作成すると、構文は次のようになります。
someprocess | mtee /+ mylogfile.txt
/ +は出力を追加することを意味します。
もちろん、これはmteeをPATHにあるフォルダにコピーしたことを前提としています。
前述のように、現在のディレクトリにある実行可能ファイルの出力を次のようにリダイレクトできます。
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のからエラーが発生します。
私はBrian Rasmussenに同意します。unxutilsの移植は、これを行う最も簡単な方法です。スクリプトページのバッチファイルセクションで、Rob van der Woudeは、MS-DOSおよびCMDコマンドの使用に関する豊富な情報を提供しています。私は彼があなたの問題のネイティブな解決策を持っているかもしれないと思った、そしてそこを掘り下げた後、私はTEE.BATを見つけた。それはかなり複雑に見えるバッチファイルであり、私の傾向はunxutilsポートを使用することです。
Windows環境のパスにcygwinがある場合は、次を使用できます。
dir > a.txt | tail -f a.txt
dir 1>a.txt 2>&1 | type a.txt
これは、STDOUTとSTDERRの両方をリダイレクトするのに役立ちます
これは非常に古いトピックであることはわかっていますが、以前の回答では、バッチで記述されたリアルタイムTeeの完全な実装はありません。以下の私の解決策は、JScriptセクションを使用してパイプコマンドから出力を取得するBatch-JScriptハイブリッドスクリプトですが、データの処理は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
file.exe 2>&1|tee.bat
:ここに見られるようなsuperuser.com/questions/452763/...
これは、他の回答の1つに基づいて私が使用したもののサンプルです
@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%
これは他のコマンドの最後にも追加できます。私が知る限り、メッセージが複数行ある場合に機能します。たとえば、次のコマンドは、エラーメッセージがある場合に2行を出力します。
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」ステートメントを含むバッチサブルーチンを使用して、コマンド出力を1行ずつ取得し、その行をファイルに書き込んでコンソールに出力しています。
@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ループを使用して、好きなことを「実行」してみてください。
for /F "delims=" %a in ('dir') do @echo %a && echo %a >> output.txt
ループ用のWindows CMDの優れたリソース:https : //ss64.com/nt/for_cmd.html ここで重要なのは、出力の各行を分割するデリミタ(delims)を何も設定しないことです。このようにして、デフォルトの空白で壊れることはありません。%aは任意の文字ですが、「do」セクションで使用され、まあ...各行で解析された文字を使用して何かを行います。この場合、アンパサンド(&&)を使用して2番目のエコーコマンドを実行し、選択したファイルに作成または追加(>>)できます。ファイルの書き込みに問題がある場合に備えて、DOコマンドのこの順序を維持する方が安全です。少なくとも最初にコンソールにエコーを取得します。最初のエコーの前のアットマーク(@)は、コンソールがエコーコマンド自体を表示するのを抑制し、代わりに、%aに文字を表示するコマンドの結果を表示します。そうでなければあなたは見るでしょう:
ドライブ[x]のエコーボリュームはWindows
ですドライブ[x]のボリュームはWindowsです
更新:/ Fは空白行をスキップし、すべての行に文字を追加して出力を事前にフィルター処理することのみを修正します(おそらくfindコマンドを使用して行番号を指定します)。CLIでこれを解決するのは、迅速でもきれいでもありません。また、私はSTDERRを含めなかったので、ここでもエラーをキャプチャしています:
for /F "delims=" %a in ('dir 2^>^&1') do @echo %a & echo %a >> output.txt
キャレット(^)は、コマンドがコマンドラインで直接入力するのではなく、解釈される文字列であるため、その後の記号をエスケープするためにあります。
UNIXと同じように。
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にリダイレクトします。UNIX / LINUXではなく、DOS、つまりWindowsコマンドプロンプトを使用して出力を表示し、出力をファイルにリダイレクトするコマンドの記述方法。
これらのコマンドは、バイタスクリプティング(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
または/?
。しかし、残りは時々うまくいくかもしれません:-)
もう1つのバリエーションは、パイプを分割し、必要に応じて出力をリダイレクトすることです。
@echo off
for /f "tokens=1,* delims=:" %%P in ('findstr /n "^"') do (
echo(%%Q
echo(%%Q>&3
)
@exit/b %errorlevel%
上記を.batファイルに保存します。また、filestream 1のテキスト出力をfilestream 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を終了)