commit-build.bat
ビルドプロセスの一部として他の.BATファイルを実行させようとしています。
内容commit-build.bat
:
"msbuild.bat"
"unit-tests.bat"
"deploy.bat"
これは非常に単純に見えcommit-build.bat
ますが、リスト(msbuild.bat
)の最初の項目のみを実行します。
問題なく各ファイルを個別に実行しました。
commit-build.bat
ビルドプロセスの一部として他の.BATファイルを実行させようとしています。
内容commit-build.bat
:
"msbuild.bat"
"unit-tests.bat"
"deploy.bat"
これは非常に単純に見えcommit-build.bat
ますが、リスト(msbuild.bat
)の最初の項目のみを実行します。
問題なく各ファイルを個別に実行しました。
回答:
使用する:
call msbuild.bat
call unit-tests.bat
call deploy.bat
CALLを使用しない場合、現在のバッチファイルは停止し、呼び出されたバッチファイルは実行を開始します。これは、初期のMS-DOS時代にさかのぼる独特の動作です。
他のすべての答えは正しいです:コールを使用してください。例えば:
call "msbuild.bat"
歴史
従来のDOSバージョンでは、バッチファイルを再帰的に実行することはできませんでした。次に、別のcmdシェルを呼び出してバッチファイルを実行し、終了時に呼び出し元のcmdシェルに実行を戻すcallコマンドが導入されました。
明らかに、以降のバージョンでは、他のcmdシェルはもう必要ありません。
初期の頃、多くのバッチファイルは、バッチファイルを呼び出しても呼び出し元のバッチファイルに戻らないという事実に依存していました。追加の構文なしでその動作を変更すると、バッチメニューシステム(メニュー構造にバッチファイルを使用)などの多くのシステムが壊れます。
したがって、Microsoftの多くの場合と同様に、下位互換性がこの動作の理由です。
チップ
バッチファイルの名前にスペースが含まれている場合は、名前を引用符で囲みます。
call "unit tests.bat"
ちなみに、バッチファイルの名前がすべてわからない場合は、forを使用してこれを行うこともできます(バッチファイル呼び出しの正しい順序は保証されません。ファイルシステムの順序に従います)。
FOR %x IN (*.bat) DO call "%x"
呼び出し後にエラーレベルに対応することもできます。使用する:
exit /B 1 # Or any other integer value in 0..255
エラーレベルを返します。0は正しい実行を示します。呼び出しバッチファイルでは、次を使用して反応できます。
if errorlevel neq 0 <batch command>
if errorlevel 1
NT4 / 2000 / XPより古いWindowsを使用している場合に使用して、すべてのエラーレベル1以上をキャッチします。
バッチファイルのフローを制御するために、goto :-(
if errorlevel 2 goto label2
if errorlevel 1 goto label1
...
:label1
...
:label2
...
他の人が指摘したように:バッチファイルを置き換えるビルドシステムを確認してください。
errorlevel
コマンド例は、(CMDコンソールで)は、Windows 10上で、私に問題を与えました。コマンドを単にに変更しましたif errorlevel neq echo Houston We have a Problem!
。私のバッチプロセスには問題がなく、ほぼ正常に完了しましたが、callステートメントの後にこのコマンドを使用する方法のすべてのステップで、「neqは現時点では予期されていませんでした」と表示されました。彼らは、等しくない構文が変更された可能性を考えて、私が試した!=
とも<>
なく、新しい構文のために同じ「現時点では期待できない」エラーを取得保管しました。私は何を間違っているのでしょうか?
複数のコマンドプロンプトを開きたい場合は、
start cmd /k
/k
:実行する必要があります。
多くのコマンドプロンプトを起動するには、次のようにします。
start cmd /k Call rc_hub.bat 4444
start cmd /k Call rc_grid1.bat 5555
start cmd /k Call rc_grid1.bat 6666
start cmd /k Call rc_grid1.bat 5570.
start "Window title" /wait cmd /k call something.bat
、物事を順番に実行するために使用したいと思うでしょう。
start "Window title" /wait cmd /c something.bat
、cmd /c
終了時にウィンドウを閉じる場所)
2つのバッチスクリプトaaa.batとbbb.batがあり、以下のように呼び出す場合
call aaa.bat
call bbb.bat
スクリプトを実行するとき、最初にaaa.batを呼び出し、aaa.batのスレッドが終了するのを待って、bbb.batを呼び出します。
ただし、aaa.batが終了してbbb.batが呼び出されるのを待ちたくない場合は、STARTコマンドを使用してみてください。
START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
[/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
[/AFFINITY <hex affinity>] [/WAIT] [/B] [command/program]
[parameters]
試験:
start /b aaa.bat
start /b bbb.bat
Start msbuild.bat
Start unit-tests.bat
Start deploy.bat
それでも解決しない場合は、交換するstart
とともにcall
またはこれを試してください。
Start msbuild.bat
Goto :1
:1
Start unit-tests.bat
Goto :2
:2
Start deploy.bat
正しい引用(これは時々トリッキーになることがあります):
start "" /D "C:\Program Files\ProgramToLaunch" "cmd.exe" "/c call ""C:\Program Files\ProgramToLaunch\programname.bat"""
1番目の引数-タイトル(この場合は空)
2番目の引数-/ Dは開始ディレクトリを指定し、現在の作業ディレクトリ(「%〜dp0」など)が必要な場合は省略できます
3番目の引数-起動するコマンド、「cmd.exe」
4番目arg-コマンド内の引数。コマンド内の引数は二重引用符で囲まれています(これにより、バッチ内の引用符内で引用符をエスケープします)
1つで複数のスクリプトを実行すると、同じ問題が発生しました。最初のスクリプトで終了していたことに気づかずに、最初のスクリプトで死ぬようにしました。
:: OneScriptToRunThemAll.bat
CALL ScriptA.bat
CALL ScriptB.bat
EXIT
:: ScriptA.bat
Do Foo
EXIT
::ScriptB.bat
Do bar
EXIT
11個すべてのスクリプトのEXIT行を削除して再試行しましたが、11個すべてが同じコマンドウィンドウで一度に1つずつ順番に実行されました。
:: OneScriptToRunThemAll.bat
CALL ScriptA.bat
CALL ScriptB.bat
EXIT
::ScriptA.bat
Do Foo
::ScriptB.bat
Do bar
exit
、代わりに置き換えますgoto :eof
。これはに「戻る」になるcall
@echo off :menu some commands goto menu
注意してください。これにより、閉じられるまで連続ループが実行されます。基本的に、::
ジャストは必要ありません:
バッチスクリプトを並列で実行する
start "systemLogCollector" /min cmd /k call systemLogCollector.bat
start "uiLogCollector" /min cmd /k call uiLogCollector.bat
start "appLogCollector" /min cmd /k call appLogCollector.bat
ここでは、3つのバッチファイルが最小化された状態で個別のコマンドウィンドウで実行されます。それらを最小化したくない場合は、を削除し/min
ます。また、後でそれらを制御する必要がない場合は、タイトルを取り除くことができます。したがって、必要最小限のコマンドは、start cmd /k call systemLogCollector.bat
それらを終了したい場合
taskkill /FI "WindowTitle eq appLogCollector*" /T /F
taskkill /FI "WindowTitle eq uiLogCollector*" /T /F
taskkill /FI "WindowTitle eq systemLogCollector*" /T /F