(for Internet Explorer)
← ▼ ▲
↑
バッチファイルのデバッグ
echo /* [DEBUGGING] */ a & pause & cls
実行中に止める
全体の動きを見る
・echo on にして、注目したい箇所に、特有のコメント、または、ファイルへリダイレクトする
echo を入れます。
REM /* [DEBUGGING] */ a
・注目したい箇所に、変数に関するコメントを入れます
・echo on にするか、バッチファイル内で set echo_on=1 に対応させて、
実行ログをファイルに出力しながら、実行するバッチファイルを作成して実行します。
REM /* [DEBUGGING] */ r=%r%
echo on
set echo_on=1
( call auto.bat 2>&1 ) > log.txt
if "%notepad%"=="" start "" notepad log.txt
if not "%notepad%"=="" start "" %notepad% log.txt
set echo_on=
x.bat
auto.bat
2>&1 で、標準エラー出力も log.txt に出力しています。
>call
実行ログで、どのバッチファイルを実行しているかどうかは、call 文を検索すれば
分かります。
if not (%rr%)==(0) echo %cd%^>&echo /* [DEBUGGING] */ %msg%&pause
→ x.lzh
→ notepad
→ x_me.lzh
または、
del "C:\batlog.txt"
echo /* [DEBUGGING] */ a >> "C:\batlog.txt"
set /A g_count = %g_count% + 1
echo g_count=%g_count% & if "%g_count%" == "1" ( pause & echo on )
指定した回数が通過したら、コマンドを表示しながら実行する。
← ▼ ▲
VisualBat - バッチファイルのデバッガー
→ VisualBat_1.0.0.zip
ダウンロード
→ バッチファイル向け統合開発環境「VisualBat」を試してみる - CX's Hatena Blog (Web)
→ 編集やデバッグが簡単になるバッチファイル向け統合開発環境「VisualBat」 - 窓の杜 (Web)
次のことができます。
・ブレーク ポイントの設定
・ステップ実行
・全変数のウォッチ
参考
次のことはできません。
・コールスタックの参照
← ▼ ▲
batlib
→ batlib フォルダー
Sage Plaisir 21 が提供する（予定の）バッチ ファイルのライブラリ。
メイン関数
@echo off
rem ********************************************************************
rem * File: batlib.bat
rem ********************************************************************
call :Main
if errorlevel 1 ( echo ^<%error_message%/^> & pause & exit /b )
exit
rem ********************************************************************
rem * Function: Main
rem * Calls test functions.
rem *
rem * Return Value:
rem * %errorlevel% - 0=Pass
rem ********************************************************************
:Main
call :T_Example "Example.txt"
if errorlevel 1 ( exit /b )
rem ★ call の直後は必ず errorlevel をチェックすること
echo Pass.
pause
goto :eof
rem ********************************************************************
rem * Function: T_Example
rem * A test function.
rem *
rem * Arguments:
rem * "%~1" - Full path of input.
rem *
rem * Return Value:
rem * %return_value% - 1=Same, 0=NotSame
rem ********************************************************************
:T_Example
set input_path=%~1
set return_value=0
goto :eof
%error_message%
errorlevel
← ▼ ▲
Error
<< batlib
ソース
→ batlib.bat
call :Error "%~1" & exit /b
エラーを発生させます。
【引数】
%~1
%errorlevel% に設定する値
%errorlevel%
%~1、ただし整数のみ
%~2
%error_message% の一部に設定するエラーメッセージ
if not exist "a.txt" ( call :Error 1 & exit /b )
サンプル
if not exist "a.txt" ( call :Error 1 "not found" & exit /b )
エラーを発生させます。
Error 関数を呼び出すと、%error_message% に次のようなエラーメッセージが入ります。
ERROR errorlevel="1" error_message=""
%error_message% を XML 形式にしなかった理由は、変数を参照したときに
リダイレクトされてしまうからです。
%~2 引数に、< や > や " を含めることはできません。
→ エラーをそのまま返す
関連
→ ClearError
エラーをクリアします。
エラーメッセージを表示して、続きを実行します。
エラーが発生したことをテストします。
%error_message% 変数
← ▼ ▲
ClearError
<< batlib
call :ClearError
エラーをクリアします。
call :T_Example
echo.
echo Next is Error Test
...
if not errorlevel 1 ( call :Error 1 & exit /b )
call :ClearError
サンプル
エラーが発生したことをチェックします。 パスしたらエラーをクリアします。
ソース
→ batlib.bat
%errorlevel% と %error_message% をクリアします。
→ エラーをそのまま返す
関連
→ Error
エラーが発生したら、エラーメッセージを表示して、続きを実行します。
サンプル
call :T_Example
if errorlevel 1 ( echo ^<%error_message%/^> & call :ClearError )
if や for の ( ) の中で errorlevel 変数を参照しないでください。
errorlevel 構文を使ってください。
( ) の前の errorlevel 変数の値が参照されてしまいます。
← ▼ ▲
GetStepPath
<< batlib
テスト
ソース
→ batlib.bat
→ batlib.bat
T_GetStepPath
call :GetStepPath "%~1" "%~2"
フル パスを相対パスに変換します。
【引数】
%~1
%~2
入力するフル パス
相対パスの基準となるフル パス
%return_value%
相対パス
親フォルダー（ピリオド２つ）が相対パスに含まれるような値を引数に指定したときは、
エラーになります。
のコードも必要です。
Error
← ▼ ▲
GetFileName
call :GetFileName "%~1"
パスからファイル名を返します。
【引数】
%~1
入力するパス。相対パス、または、フル パス
ファイル名、または、フォルダー名
%return_value%
サンプル
C:\Folder\Example.txt
%~1
%return_value%
Example.txt
C:\Folder
Folder
C:
なし（エラー）
なし
なし（エラー）
テスト
ソース
→ batlib.bat
→ batlib.bat
T_GetFileName
Folder\Example
Folder
Example
Folder
参考
→ ファイル名、パス
のコードも必要です。
Error
← ▼ ▲
GetParentPath
call :GetParentPath "%~1"
親フォルダーのパスを返します。
【引数】
%~1
入力するパス。相対パス、または、フル パス
%~1 の親フォルダーのフル パス
%return_value%
サンプル
C:\Folder\Example
%~1
%return_value%
C:\Folder
C:\Folder
C:
C:
なし（エラー）
なし
なし（エラー）
テスト
ソース
→ batlib.bat
→ batlib.bat
T_GetParentPath
Folder
C:\Current\Folder （カレントが C:\Current の場合）
参考
→ ファイル名、パス
のコードも必要です。
Error
← ▼ ▲
SearchParent
GetParentPath,
のコードも必要です。
Error
call :SearchParent "%~1"
StepPath に指定したファイルまたはフォルダを、親フォルダに向かって探します。
【引数】
%~1
ファイル名、または相対パス
見つかったファイルまたはフォルダのフル・パス
%return_value%
サンプル
B2
%~1
%return_value%
C:\A\B\B2
テスト
ソース
→ batlib.bat
→ batlib.bat
T_SearchParent
カレント フォルダーが、C:\A\B\C で、下記のフォルダーまたはファイルがあるとき、
C:\A\A2
A2
C2
C:\A\B\C\C2
C:\A\B\B2
B\B2
引数と返り値の関係は、以下のようになります。
C:\A\A2
C:\A\B\B2
C:\A\B\C\C2
C:\A\B\C
NotFound
なし（エラー）
← ▼ ▲
IsSameFolder
未対応
テスト
ソース
→ batlib.bat
→ batlib.bat
T_IsSameFolder
参考
→ バッチにてフォルダ内ファイルの差分抽出 - 楽天 みんなで解決！Ｑ＆Ａ (Web)
サブ フォルダーは比較しない
← ▼ ▲
パラメータ、プログラムのチェック
set prog="%ProgramFiles%\prog\prog.exe"
if not exist %prog% echo %prog% が見つかりません & echo exit. & pause & goto :eof
%prog% %1
プログラムを呼び出すときは、次のようにバッチファイルの先頭で、プログラムの存在をチェック
するようにしてください。
バッチファイルにパラメータが必要なときは、次のようにチェックします。
%1 ではなく %~1 にしているのは、"" が付いていたらカットするためです。
if "%~1"=="" echo 使い方: %bat_name% (folder) & echo exit. & pause & goto :eof
パラメータに指定したパスを、プログラムに渡すときは、"%1" ではなく "%~1" を記述してください。
%prog% "%~1"
%*
すべてのパラメータ
バッチファイルがある場所から相対パスで実行ファイルを指定するときは、"" で囲んだ相対パス
の先頭に、%~d0%~p0 を記述してください。
→ ファイル名、パスの変数の活用
"%~d0%~p0..\Sample.exe" "%~1"
shift を実行しても、パラメーターは減りません。
← ▼ ▲
変数の活用
標準出力
>echo set a=1 > s.bat
>call s.bat
>del s.bat
>echo %a%
1
… 任意のプログラムの標準出力のつもり
… call 先で設定した環境変数が使える
→ 部分文字列
→ 日付 (timedate)
→ 標準出力
→ 計算
→ set /?
→ プロセス間の環境変数の引継ぎ
→ 遅延環境変数
→ 比較 (if)
→ set /p ：ユーザーに任意の文字列を入力させる
→ 置き換え、置換
→ ファイル名、パス
set VAR=value
%VAR%
set VAR2=%VAR%
call :Sub "%VAR%"
if "%VAR%" == "" ( )
… 代入する値は、" " で囲まないこと
… call やコマンドの引数は、" " で囲めます
… if の条件式の中は、" " で囲めます
… 変数に値を代入します
… 変数の値を参照します
= の後に空白を入れると、値の先頭が空白になります。
← ▼ ▲
>set STR=ABCDEFGHIJKL
>echo %STR:~2,5%
CDEFG
部分文字列
… 3文字目から 5文字取り出す（2文字目からではない）
echo %STR:~0,3%
… 左から 3文字取り出す
echo %STR:~-3%
… 右から 3文字取り出す
echo %STR:~4%
… 左から 3文字目以降を取り出す
echo %STR:~0,-1%
rem // Cut a last character.
… 右から 1文字削除する
:~0,3
:~2,5
:~-3
:~4
:~0,-1
← ▼ ▲
置き換え、置換
@echo off
set file_name=C:\Folder\File.txt
echo %file_name:\=/%
pause
%（変数名）:（置き換える前）=（置き換えた後）%
サンプル
C:/Folder/File.txt
バッチファイル：
結果：
→ batプログラミング基本事項まとめ - どーでもえぐぜ (Web)
参考
引数は置き換えできません。
← ▼ ▲
ファイル名、パス
%1="C:\Users\user1\Desktop\新しいテキスト ドキュメント.txt"
%~1=C:\Users\user1\Desktop\新しいテキスト ドキュメント.txt
%~d1=C:
%~p1=\Users\user1\Desktop\
%~n1=新しいテキスト ドキュメント
%~x1=.txt
%~nx1=新しいテキスト ドキュメント.txt
%~f1=C:\Users\user1\Desktop\新しいテキスト ドキュメント.txt ... full name
%~s1=C:\Users\user1\Desktop\新しい~1.TXT ... short name
%~t1=2012/07/05 20:33 ... time stamp
%~z1=895 ... file size
%~a1=--a------ ... attribute
%0 〜 %9 については、上記の記述が使えます。
任意の環境変数については、下記のように
call の引数
を活用してください。
→ GetFileName
→ GetParentPath
→ SearchParent
たとえば、%~d0%~p0 は、バッチファイルがあるフォルダー\ になります。
← ▼ ▲
日付 (%date%, %time%, timedate)
>echo %date%
2007/07/18
>echo %time%
13:43:11.81
ただし、地域やバージョン依存になるため、お勧めできない。
→ timedate.lzh
"%batchlib_dir%\timedate.exe" > _t.bat & call _t.bat & del _t.bat
echo %now%
例） 070101_2359
set now=070101_2359
標準出力に、次の内容を出力します。
次のように使うことができます。
timedate2.exe
timedate.exe
次のように使うことができます。
call などを使っているのは、子プロセスから親プロセスへ環境変数を引き継げない
ためです。
REM 現在の時刻（ローカルタイム）
"%batchlib_dir%\timedate2.exe" now_var=now >_t.bat& call _t.bat& del _t.bat
echo %now_var%
未対応
REM タイムスタンプ・更新日時
timedate2.exe t_var=update "C:\folder\file.txt" >_t.bat& call _t.bat& del _t.bat
echo %t_var%
書式：
timedate2.exe [(環境変数名)=(コマンド)] [(ファイルパス)]
→ timedate2.exe
→ timedate.exe
現在の時刻やタイムスタンプを、環境変数に設定します。
→ バッチ・ファイル中で日付をファイル名に使用する − ＠IT (Web)
→ ファイル名、パス
タイムスタンプは、%~t1
→ 置き換え
ただし、/ （スラッシュ）や : （コロン）はフォルダー名に使えないので、
%~t1
地域やバージョン依存になるため、お勧めできないが、単に識別するためなら使える。
:GetTimeStampFolderName
set a_string=%~t1
set a_string=%a_string:/=-%
set a_string=%a_string::=;%
set return_value=%a_string%
goto :eof
→ PowerShell - タイムスタンプを取得する (LastWriteTime)
← ▼ ▲
計算
set a=1
set b=2
set /A c = %a% + %b%
echo %c%
数値計算は、set /A でできます。
← ▼ ▲
プロセス間の環境変数の引継ぎ
子プロセスから親プロセスへ環境変数を引き継げません。
.exe ファイルを起動すると、新しくプロセスを作成し、起動をトリガしたプロセスの
環境変数のコピーを、新しいプロセスの環境変数にします。
PCの環境変数を変更しても、各プロセスに反映されません。
バッチファイルに環境変数でデータを返すときは、call で呼び出すバッチファイルを
作成します。
→ call & 引数
RunBat (vbslib)
でバッチファイルを実行する場合、環境変数を設定するバッチ
ファイルを call する代わりに、バッチファイルの内容を、RunBat のパラメーターに
ReadFile (vbslib) で埋め込むと、バッチファイルによって設定する環境変数を引き
継ぐことができます。
← ▼ ▲
cmd.exe 環境変数を表示、設定、または削除します。
SET [変数名=[文字列]]
変数名 環境変数名を指定します。
文字列 変数に割り当てる文字列を指定します。
現在の環境変数を表示するには、パラメータを指定せずに SET と入力してください。
コマンド拡張機能を有効にすると、SET は、次のように変更されます:
等号や値を指定せずに、変数名だけを指定して SET コマンドを実行すると、
SET コマンドに指定された名前に接頭辞が一致するすべての変数の値が
表示されます。たとえば、
SET P
と入力すると、文字 'P' で始まるすべての変数が表示されます。
変数名が現在の環境に見つからない場合は、SET コマンドは、ERRORLEVEL を
1 に設定します。
SET コマンドでは、変数の名前に等符号を使用することはできません。
SET コマンドには、2 つの新しいスイッチが追加されています:
SET /A 式
SET /P 変数=[プロンプト文字列]
/A スイッチは、等号の右側の文字列が、評価すべき数式であることを
指定します。式の評価はごく単純で、次の操作がサポートされます。
操作は、優先順位の高い順に示されています:
() - グループ化
! ~ - - 単項演算子
* / % - 算術演算子
+ - - 算術演算子
<< >> - 論理シフト
& - ビット演算子 AND
^ - ビット演算子排他的 OR
| - ビット演算子 OR
= *= /= %= += -= - 代入
&= ^= |= <<= >>=
, - 式の区切り記号
論理演算子またはモジュール演算子を使う場合は、式文字列を引用符で
囲む必要があります。式内の数値以外の文字列は環境変数文字列として
処理され、使用される前に数値に変換されます。指定された環境変数名が
現在の環境で定義されていない場合は、値として 0 が使用されます。
これにより、いくつもの % 記号を入力して値を取得しないでも、環境
変数の値を算術演算に使うことができます。
コマンド スクリプト外でコマンド ラインから SET /A を実行すると、式の
最終的な値が表示されます。割り当て演算子を使うには、割り当て演算子
の左側に環境変数名が必要です。数値は 10 進数ですが、接頭辞として 0x
を付けると 16 進数、0 を付けると 8 進数になります。従って、0x12 は 18、
あるいは 022 と同じです。8 進表記を使う場合は、注意してください。08 や
09 は、8 と 9 が有効な 8 進数ではないため、有効な数値ではありません。
/P はユーザーによって入力された入力行を変数の値として設定できるようにします。
入力行を読み取る前に、指定されたプロンプト文字列を表示します。プロンプト文
字列は空でもかまいません。
環境変数の置換は、次のように拡張されます:
%PATH:文字列1=文字列2%
は、PATH 環境変数を展開し、その結果に含まれるすべての "文字列1" を
"文字列2" に置き換えます。"文字列2" に空の文字列を指定すると、展開
された出力からすべての "文字列1" を削除することができます。"文字列1"
をアスタリスクで始め、展開された出力の先頭から、文字列1 の残りの部分
が最初に現れるまでのすべてを一致させることもできます。
また、展開の副文字列を指定することもできます。
%PATH:~10,5%
は、PATH 環境変数を展開し、展開結果の 11 番目 (オフセット 10) の文字
から始まる 5 文字だけを使います。長さが指定されなかった場合は、変数の
値の残りの長さを既定値とします。オフセットまたは長さのどちらかが負の値
の場合、環境変数の値の長さに指定されたオフセットまたは長さを足してその
数を使います。
%PATH:~-10%
は、パス変数の最後の10 文字が展開されます。
%PATH:~0,-2%
は最後の 2 文字以外のすべてが展開されます。
最後に、遅延環境変数の展開が追加されました。このサポートは常に既定で
無効になっていますが、CMD.EXE の /V: のコマンド ライン スイッチを使
って有効または無効にできます。CMD /? を参照してください。
遅延環境変数の展開は、実行時ではなく、テキスト行を読み取るときに展開
されるという現在の制限を避けるために役立ちます。
次の例は即時変数展開の問題を説明しています。
set VAR=before
if "%VAR%" == "before" (
set VAR=after;
if "%VAR%" == "after" @echo If you see this, it worked
)
この例は、論理的には IF 文が別の IF 文の本体に含まれる複合文なので、
両方の IF 文の %VAR% が、最初の IF 文を読み取ったときに展開されます。
このため、メッセージは決して表示されません。複合文の中の IF では "before"
と "after" が比較され、決して等しくはなりません。同様に次の例も期待し
たようには動作しません。
set LIST=
for %i in (*) do set LIST=%LIST% %i
echo %LIST%
この例では、現在のディレクトリのファイルの一覧は作成されず、代わりに最後
に見つけられたファイルが LIST 変数に設定されます。これは %LIST% が FOR 文
が読み取られるとき、一度だけ展開され、そのときは LIST 変数は、空だからです。
つまり、実際に実行されている FOR ループは
for %i in (*) do set LIST= %i
で、LIST に最後にみつけられたファイルを設定し続けているだけです。
遅延環境変数の展開では、実行時に環境変数を展開するために異なった文字
(感嘆符)を使うことができます。遅延環境変数の展開が有効な場合、上記の
例は次のように書くと意図したように動作します。
set VAR=before
if "%VAR%" == "before" (
set VAR=after
if "!VAR!" == "after" @echo If you see this, it worked
)
set LIST=
for %i in (*) do set LIST=!LIST! %i
echo %LIST%
コマンド拡張機能が有効な場合、SET によって表示される変数の一覧には
現れないいくつかの動的な環境変数があります。これらの変数の値は、変数の
値が展開されるときに動的に計算されます。ユーザーがこれらの名前の変数を
明示的に定義する場合、その定義は下記の動的な定義を無効にします。
%CD% - 現在のディレクトリ文字列に展開します。
%DATE% - DATE コマンドと同じフォーマットで現在の日付に展開します。
%TIME% - TIME コマンドと同じフォーマットで現在の時刻に展開します。
%RANDOM% - 0 から 32767 の間の任意の 10 進数に展開します
%ERRORLEVEL% - 現在の ERRORLEVEL の値に展開します。
%CMDEXTVERSION% - 現在のコマンド プロセッサ拡張機能のバージョン番号に
展開します。
%CMDCMDLINE% - コマンド プロセッサを起動したオリジナル コマンドライン
に展開します。
set /?
←
↓