(for Internet Explorer)
エラー in C:\folderA\folderB\out.txt
C:\folderA がソースをインストールした任意のフォルダで、次のような出力結果が正しいとき、
out_ans.txt
そこで、out_ans.txt をバッチファイルで作成することで、インストールした状態が変わっても
自動的に判定することができるようになります。
C:\folderA の部分は、インストールした状態によって変わってしまいます。
つまり、単純なファイルの比較で、出力結果が正しいかどうかを自動的に判定することが
できません。
pushd ..\..
set base=%cd%
popd

set out=out_ans.txt
if exist %out% del %out%
echo エラー in %base%\folderB\out.txt>>%out%
echo.>>%out%

set out=
set base=
T_ALL_4_setup.bat
←ここを修正する
←ここで絶対パスを得る
絶対パスをすべて大文字にするとき
ツールによっては出力結果を勝手に大文字だけにするものがある。
これに対処するには、次のようにして、大文字だけが入った base_i 環境変数を使う。
cscript //nologo set_base_i.vbs > _set.bat & call _set.bat & del _set.bat
echo %base_i%\FILE.TXT
T_ALL_4_setup.bat
Set  g_sh = WScript.CreateObject("WScript.Shell")
WScript.Echo  "Set base_i="+ UCase( g_sh.CurrentDirectory )
set_base_i.vbs
Test.vbs
Sub  test_setup( tests )
  Dim  base : base = g_sh.GetAbstructPathName( "..\.." )
  Dim  f : Set f = g_fs.CreateTextFile( "out_ans.txt", True, False )
  f.WriteLine  "エラー in " + base + "\folderB\out.txt"
  f.WriteLine  ""
  Pass
End Sub
echo エラー in %base%\folderB\out.txt
echo.
out_ans.txt
..\..
out_ans.txt
"エラー in " + base + "\folderB\out.txt"
..\..
内部用と公開用、外部依存モジュールあり/なし、ソースパッケージとバイナリパッケージ、
のようにファイルの構成が大きく異なるときは、1つのフルパッケージから、それぞれの
パッケージを自動的に作成できるようにするとよいでしょう。
REM --- package name ---
set p=ModuleA
call :rmdir                            %p%

REM --- copy folder ---
call :copy   ..\Modules_src\ModuleA    %p%\ModuleA
 if %r%==1 goto :eof
call :copy   ..\Modules_src\ModuleB    %p%\ModuleB
 if %r%==1 goto :eof
modules_src
ModuleA
ModuleB
_pack
ModuleA_src
Modules_src
サンプル・パッケージの構成例
ModuleA_make.bat
Modules_make.bat
フルパッケージ
ModuleA のみのパッケージ
ModuleA と ModuleB を組み合わせたパッケージ
ModuleA_src フォルダを作成するバッチファイル
Modules_src フォルダを作成するバッチファイル
・ライブラリのソース、またはバイナリ
・ライブラリを使うアプリのサンプル
コンパイルエラーとリンクエラーをチェックするために、最低限下記のものが必要です。
この構成で、動作確認を行います。
rmdir, copy サブルーチンを使ったサンプル:
サンプル:
→ ver_pack.lzh
Modules_src
マスターファイル(コピー元)
ModuleA_patch
ModuleA をコピーした後に上書き修正するファイル
@echo off
if "%~1"=="" cmd /K %0 /wnd %1 %2 %3 %4
shift

pushd ..
REM  base folder is vbslib_new
echo base folder is %cd%
echo OK?
pause
     
set src_name=vbs_inc.vbs
set src=TestByFCBat\vbs_inc\vbslib\%src_name%
for /R %%i in (%src_name%) do (
  if exist "%%i" if not "%cd%\%src%"=="%%i" (
    fc /A "%src%" "%%i"
    if errorlevel 1 explorer /select, "%%i"&goto fin
  )
)

:fin
echo.
echo done in %cd%
echo.
popd
set src_name=
set src=
比較&選択
    echo %%i
    xcopy /D "%src%" "%%i"
コピー
fc の行を変えます
src_name と src を、
マスターファイルの
パスにします
複数のフォルダにある同じ名前のファイルの内容を同じにします。

内容が異なると、マスターではない方のファイルを自動的に選択します。
do.bat
project_template
src
test
alltest
test1
alltest.bat
call_do.bat
do_each.bat
setting.bat
(a) メイン・バッチ
(d) 内部用(コール・バッチ)
(c) フォルダ一覧 (要修正)
(b) 環境変数設定 (要修正)
do.bat
(e) クリーン、ビルド、テストなどを実行 (要修正)
(e) クリーン、ビルド、テストなどを実行 (要修正)
alltest.bat
setting.bat
do_each.bat
call_do.bat
do.bat
(a) メイン・バッチ
(b) 環境変数設定 (要修正)
(c) フォルダ一覧 (要修正)
(d) 内部用(コール・バッチ)
(e) クリーン、ビルド、テストなどを実行 (要修正)
>auto
全フォルダのクリーン→リビルド→テストを実行します。
バッチファイルを起動するときは、カレントディレクトリに起動するバッチファイルが
ある状態で行ってください。
all
デフォルトの実行を表示して確認してから実行します。
>do build
1つのフォルダのリビルドを行います。
auto.bat と do.bat のパラメータに指定できるのは、次のとおりです。
(なし)
全フォルダのクリーン→ビルド→テスト→クリーンを実行します。
build
test
clean
リビルドを実行します。
テストを実行します。
クリーンを実行します。
全フォルダ(alltest.bat)、または1つのフォルダ(do.bat)に対して、ビルドやテストなどを行います。
テンプレート
if exist Build.dat  del Build.dat
if exist Build.wrn  del Build.wrn
if exist Build.err  del Build.err
if exist Build.log  del Build.log

set rmdir_path=obj
if exist %rmdir_path%  rmdir /S /Q %rmdir_path%
if exist %rmdir_path%  echo cannot delete %rmdir_path% & set r=1& goto :eof
set rmdir_path=
→ clean
PB delete
→ コマンドライン・コンパイル(VS2005)
→ batchlib.lzh
→ vbslib.lzh
vbslib 製テスト・プロンプトをお使いください。
echo ----- reset test folder -----
if exist test_do  rmdir /S /Q test_do
mkdir test_do
xcopy /E /Y original test_do
echo cd .. & a.bat > a.bat
original フォルダ
テストを実行するバッチファイルの一部
リセット状態のファイル構成が入ったフォルダ
test_do フォルダ
リセットするテスト実施用フォルダ
test_do フォルダを一度削除し、originai フォルダの内容と一致させます(リセットします)。
clean.bat
for /D /R %%i in (test_do) do if exist "%%i" rmdir /S /Q "%%i"
テスト終了後に、すべての test_do フォルダを削除します
echo off
echo ----- setup tools -----
call ..\common\setting.bat
if (%test_prog%)==() echo not set %%test_prog%% & set r=1 & if (%no_pause%)==() pause & goto :eof
if not exist %test_prog% echo not found %test_prog% & set r=1 & if (%no_pause%)==() pause & goto :eof

set  case=test1
echo ----- %case% -----
%test_prog% %case%  > %case%_out.txt
%feq% %case%_out.txt %case%_ans.txt
if errorlevel 1  echo NG & set r=1 & if (%no_pause%)==() pause & goto :eof

set r=0 & echo Pass. if (%no_pause%)==() pause
REM ----- common setting -----
set test_prog="..\..\Debug\prog.exe"
プログラムのパスは、デバッグ版とリリース版、また、Program Files に入っていたりして、
変わることがよくあります。 そこで、各テストバッチファイルから、テストグループ共通の
setting.bat を呼び出すようにします。
setting.bat
clean.bat
del out1.txt
notepad.exe は、結果の表示に使うことができます。
if "%notepad%"=="" start "" notepad log.txt
if not "%notepad%"=="" start "" %notepad% log.txt
下記のバッチファイルは、notepad 環境変数が設定してあったら、別のプログラムで
log.txt を表示します。
me 設定
set notepad="C:\Program Files\sted\sted.exe"
all_test.bat
echo off

pushd test1
call test1.bat
popd
if not %r%==0  echo NG & set r=1 & goto :eof

set r=0 & echo Pass.
:eof2
if "%1"==""  pause
各テストのバッチファイルを呼び出し、テスト結果が入った環境変数をチェックします。
最後に表示される Pass か NG で全テストの結果を判定をします。
set errorlevel しても if errorlevel で判定できません。
.exe 形式の main 関数の返り値は、エラーレベルに格納されます。
if errorlevel 1  echo NG & set r=1 & goto :eof
1以上ならNG
if not errorlevel 1  echo NG & set r=1 & goto :eof
0 なら NG
echo %errorlevel% でエラーレベルの値が分かります。
errorlevel
エラーレベル
環境変数 r に代入していますが、これは、後述する全テスト実行バッチのためです。
set r=0 & echo Pass.
:eof2
if "%1"==""  pause
NG が無く、バッチファイルの最後まで来たら、次のように Pass したことを明示します。
参考
errorlevel 構文を使う
errorlevel 変数を使う
cscript sample.vbs
if not "%errorlevel%"=="21"  echo ERROR & pause & goto :eof
Windows2000以降?
cmd /v:on /c "prog1 & echo exit /b !ERRORLEVEL! > _tmp.bat" | prog2
call _tmp.bat
echo %ERRORLEVEL%
パイプの前段のエラーレベルを知りたいとき
関連
→ 終了コード (Linux)
echo /* [DEBUGGING] */   a   & pause & cls
実行中に止める
全体の動きを見る
・注目したい箇所に、特有のコメント、または、ファイルへリダイレクトする 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
and の使い方が誤っています。
上記は、次の命令に対するエラーです。
→ x_me.lzh
または、
del  "C:\batlog.txt"
echo  /* [DEBUGGING] */  a  >> "C:\batlog.txt"
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="c:\file.txt" になります。
%prog% %1
%*
すべてのパラメータ
NUL リダイレクト
dir > nul
何も表示しません
環境変数を設定するバッチファイルの出力
echo set /A a=1 > setting.bat
call  setting.bat
echo (%a%)
/A をつけないと、a="1" ではなく、a="1 " になってしまいます。
2>&1
で、標準エラー出力を、標準出力します。
( call bad.bat  2>&1 ) > log.txt
サンプル
標準入力の自動化
echo F | xcopy a.txt b.txt
xcopy a.txt b.txt < input.txt
xcopy に F と入力する
xcopy に input.txt の内容を入力
dir 2> nul
エラー出力は表示しません
( call bad.bat  2>&1 ) | tee log.txt
標準出力しながら、ファイルに出力する
( call bad.bat  2>&1 ) | safetee -o log.txt
command 2> err.txt
で、標準エラー出力をリダイレクトします。
→ safetee コマンド
子プロセスを起動するプログラムのリダイレクトの注意
それぞれのプロセスが printf する内容をファイルにリダイレクトした場合、
それぞれのプロセスごとに出力内容が集まります。 おそらく、バッファ
リングされているためと思われます。
process A 1
process B 1
process A 2
process B 2
リダイレクトしない場合
リダイレクトする場合
process A 1
process A 2
process B 1
process B 2
>call /?
バッチ プログラムを別のバッチ プログラムから呼び出します。

CALL [ドライブ:][パス]ファイル名 [バッチパラメータ]

  バッチパラメータ   バッチ プログラムで必要なコマンド ライン情報を指定します。

コマンド拡張機能を有効にすると、CALL は次のように変更されます:

CALL コマンドは、CALL のターゲットとしてラベルを受け付けるようになります。
構文は、次のとおりです:

    CALL :ラベル 引数

指定された引数で新しいバッチ ファイル コンテキストが作成され、指定
されたラベルの次の文に制御が渡されます。バッチ スクリプト ファイルの
最後に 2 回到達することによって、2 回 "終了" する必要があります。
1 回目に最後に到達したときには、制御は CALL 文の次の行に返されます。
2 回目に、バッチ スクリプトが終了します。バッチ スクリプトから "戻る"
ための GOTO :EOF 拡張機能の説明については、GOTO /? と入力してください。

また、バッチ スクリプトの引数参照 (%0、%1 など) の展開は、次のように
変更されました:


    %* バッチ スクリプト内では、すべての引数 (%1、%2、%3、%4、
        %5 など) を参照します。

    バッチ パラメータ (%n) の置換は拡張されました。次のオプション構文
    を使うことができます:

        %~1         - すべての引用句 (") を削除して、
                      %1 を展開します。
        %~f1        - %1 を完全修飾パス名に展開します。
        %~d1        - %1 をドライブ文字だけに展開します。
        %~p1        - %1 をパスだけに展開します。
        %~n1        - %1 をファイル名だけに展開します。
        %~x1        - %1 をファイル拡張子だけに展開します。
        %~s1        - 展開されたパスは、短い名前だけを含みます。
        %~a1        - %1 をファイル属性に展開します。
        %~t1        - %1 をファイルの日付/時刻に展開します。
        %~z1        - %1 をファイルのサイズに展開します。
        %~$PATH:1   - PATH 環境変数に指定されているディレクトリを
                      検索し、最初に見つかった完全修飾名に %1 を
                      展開します。環境変数名が定義されていない場合、
                      または検索してもファイルが見つからなかった
                      場合は、この修飾子を指定すると空の文字列に
                      展開されます。

    修飾子を組み合わせて、複合結果を得ることもできます:

        %~dp1       - %1 をドライブ文字とパスだけに展開します。
        %~nx1       - %1 をファイル名と拡張子だけに展開します。
        %~dp$PATH:1 - PATH 環境変数に指定されているディレクトリを
                      検索して %1 を探し、最初に見つかったファイル
                      のドライブ文字とパスだけに展開します。
        %~ftza1     - %1 を DIR の出力行のように展開します。

    上の例の %1 と PATH は、ほかの有効な値で置き換えることができ
    ます。%~ 構文は有効な引数の数によって区切られます。%~ 修飾子
    は %* と同時には使用できません。
call 先で設定した環境変数は、戻ってきても引き継がれます。
goto :eof
call 元へ戻ります。
call 先で設定された環境変数は、 call に続いて & で同じ行に書いた次の命令では
反映されていません。 call の次の行で反映されます。
set rr=0

call  sub.bat & echo (%r%)
echo (%r%)

:sub_ret
set r=%rr%
goto ret
main.bat
sub.bat
set r=1
出力
(0)
(1)
第1引数を処理名にすると、同じファイルの中で call することができます。
@echo off
set _this=%0
if "%1"=="" goto _main
if "%1"=="_sub" shift & goto _sub
echo ERROR! invalid param1 of %_this% & pause & goto ret

:_main
echo _main
call %_this% _sub 1
pause
goto :ret

:_sub
echo _sub %1
goto :ret

:ret
set _this=
出力
_main
_sub 1
→ バッチファイル・テンプレート
コマンドプロンプトで入力したバッチファイル名になります。
>sample
sample
>..\sample.bat
..\sample.bat
バッチファイルをダブルクリックしたら、"" で囲まれたフルパスになります。
"C:\dir\file.bat"
>sample.bat "a b"
%1="a b"
%~1=a b
call  a.bat
call  :label  param1 ...
同じバッチファイルの中をコール。 %1 などは置き換わります
call 元へ戻ります。 (すぐにバッチファイルを終了する方法は不明。)
goto :eof
型チェックが無いので、ライブラリの引数の構成が変わると、移植が大変になります。
たとえば a_ で始まる環境変数を、パラメータ用にするとよいでしょう。
set  a_paramX=
set       a_Y=
リターンする直前や、初期化時に、a_ で始まる環境変数はリセットしてください。
goto ret
:ret
REM ^>call_return  %0
別ファイルコール
同ファイルコール
call :label ... > log.txt とすると、サブルーチンの出力をすべてリダイレクトします。