タスクを実行し、出力をテキストファイルに送信するバッチスクリプトがあります。コンソールウィンドウにも出力を表示する方法はありますか?
例えば:
c:\Windows>dir > windows-dir.txt
dir
の出力をコンソールウィンドウに表示する方法と、テキストファイルに出力する方法はありますか?
いいえ、純粋なリダイレクトではできません。
しかし、いくつかのトリック( tee.bat など)を使えばできます。
リダイレクトについて少し説明しようと思います。
> fileまたは<fileで10個のストリームの1つをリダイレクトします
リダイレクトがコマンドの前後にある場合は重要ではないため、これらの2行はほぼ同じです。
dir > file.txt
> file.txt dir
この例のリダイレクトは、1>のショートカットにすぎません。つまり、ストリーム1(STDOUT)がリダイレクトされます。
したがって、2> err.txtのような番号を前に付けてストリームをリダイレクトできます。また、複数のストリームを1つにリダイレクトすることもできますライン。
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
「1つしか存在できません」、それは常に最後の1つです!
したがって、dir> two.txtと等しくなります
ストリームを別のストリームにリダイレクトするという1つの追加の可能性があります。
dir 1>files.txt 2>&1
2>&1stream2をstream1にリダイレクトし、1> files.txtリダイレクトallfiles.txt.
順序はここで重要です!
dir ... 1>nul 2>&1
dir ... 2>&1 1>nul
異なっています。最初のものはすべて(STDOUTとSTDERR)をNULにリダイレクトします。
しかし、2行目はSTDOUTをNULにリダイレクトし、STDERRを「空の」STDOUTにリダイレクトします。
1つの結論として、なぜオタヴィオデシオとアンディノルマンクスの例がうまくいかないのかは明らかです。
command > file >&1
dir > file.txt >&2
どちらもstream1を2回リダイレクトしようとしますが、「1つしか存在できません」であり、常に最後のものです。
だからあなたは
command 1>&1
dir 1>&2
また、最初のサンプルでは、stream1からstream1へのリダイレクトは許可されていません(あまり役に立ちません)。
それが役に立てば幸い。
次のように、WindowsバージョンのUNIX teeコマンド( http://unxutils.sourceforge.net にあります)を使用します。
mycommand > tee outpu_file.txt
STDERR出力も必要な場合は、次を使用します。2>&1
は、STDERR出力をSTDOUT(プライマリストリーム)に結合します。
mycommand 2>&1 | tee output_file.txt
リアルタイムでの出力が必要ない場合(つまり、プログラムが書き込み中)、追加することができます
type windows-dir.txt
その行の後。
私のために働いた解決策は: dir> a.txt | type a.txt 。
はい、単一のコマンド出力をコンソール(画面)とファイルに表示する方法があります。あなたの例を使用して、使用...
@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
command > file >&1
出力ファイルを置き換える代わりに追加する場合は、使用することができます
dir 1>> files.txt 2>> err.txt
または
dir 1>> files.txt 2>>&1
私はatnの答えが好きですが、 wintee としてダウンロードするのは簡単ではありませんでしたユーティリティ)。これについては、 Windowsコマンドプロンプト出力の表示とファイルへのリダイレクト に対するdavorの回答から学びました。ここでは、UNIXユーティリティへの参照も見つかります。
Cmd画面とログの両方へのリアルタイム出力を処理できる単純な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
そして、ここにコンパイルするツールがない場合のTee.exeを含むリポジトリがあります https://github.com/iamshiao/Tee
私のオプションはこれでした:
メッセージを受け取り、コンソールとログファイルの両方に送信するプロセスを自動化するサブルーチンを作成します。
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
メッセージに変数を追加する場合、サブルーチンに送信する前に必ず引用符を削除してください。そうしないと、バッチが台無しになります。もちろん、これはエコーに対してのみ機能します。
「Tomas R」が提供するソリューションは、OPの質問に最適に機能し、ネイティブで利用できます。
試してください:chkdsk c:> output.txt | output.txtと入力します
このコマンドの出力には、ファイルにシリアル出力される完了率が含まれているため、少し乱雑に見えます(つまり、進行中にテキストが追加されます)。これは、STDOUT(画面)に出力されるビットには発生しません。リダイレクトせずに同じコマンドを実行するだけの場合はどうでしょう。