web-dev-qa-db-ja.com

DOSバッチファイルにIFブロックを含めることはできますか?

DOSバッチファイルでは、ステートメント本文の場合、1行しか使用できませんか? Cのようなプログラミング言語で使用される()と同様にifブロックに{}を使用できることをどこかで見つけたと思いますが、これを試してもステートメントは実行されません。エラーメッセージもありません。この私のコード:

if %GPMANAGER_FOUND%==true(echo GP Manager is up
goto Continue7
)
echo GP Manager is down
:Continue7

奇妙なことに、バッチファイルを実行しても「GPマネージャーが起動している」または「GPマネージャーが停止している」というメッセージが表示されません。

88
Hugh Darling

実際、条件の後に実行するステートメントのブロックを作成して配置できます。しかし、構文が間違っています。括弧は、示されているとおりに正確に使用する必要があります。

if <statement> (
    do something
) else (
    do something else
)

ただし、else-ifステートメントの組み込み構文があるとは思わない。残念ながら、それを処理するためにifステートメントのネストされたブロックを作成する必要があります。


第二に、その%GPMANAGER_FOUND% == trueテストは私にとって非常に疑わしいものです。環境変数が何に設定されているのか、どのように設定されているのかはわかりませんが、表示したコードが探している結果を生成することは非常に疑わしいです。


次のサンプルコードは正常に機能します。

@echo off

if ERRORLEVEL == 0 (
    echo GP Manager is up
    goto Continue7
)
echo GP Manager is down
:Continue7

サンプルコードに関するいくつかの具体的な詳細に注意してください。

  • 条件ステートメントの終わりと開き括弧の間に追加されたスペース。
  • 実行時にコンソールに出力されるステートメントのallが表示されないように@echo offを設定し、代わりにそれらの出力のみを表示します具体的にはechoで始まります。
  • 組み込みのERRORLEVEL変数をテストとして使用しています。続きを読む こちら
127
Cody Gray

論理的には、Codyの答えはshould workです。ただし、コマンドプロンプトがコードブロックを論理的に処理するとは思わない。私の人生では、ブロック内の単一のコマンド以上で適切に動作させることはできません。私の場合、徹底的なテストにより、ブロック内のすべてのコマンドがキャッシュされ、ブロックの終わりに同時に実行されることが明らかになりました。もちろん、これは期待した結果をもたらしません。単純化した例を次に示します。

if %ERRORLEVEL%==0 (
set var1=blue
set var2=cheese
set var3=%var1%_%var2%
)

これはshould var3に次の値を提供します。

blue_cheese

しかし、代わりに得られます:

_

コードブロックを終了すると、3つのコマンドがすべてキャッシュされ、同時に実行されるためです。

Ifブロックを書き直して1つのコマンド-goto-を実行し、いくつかのラベルを追加することで、この問題を克服できました。不器用で、私はあまり好きではありませんが、少なくとも機能します。

if %ERRORLEVEL%==0 goto :error0
goto :endif

:error0
set var1=blue
set var2=cheese
set var3=%var1%_%var2%

:endif
13
Nick

このgoto混乱の代わりに、アンパサンド&またはダブルアンパサンド&&(errorlevel 0の条件付き)をコマンド区切り文字として使用してみてください。

このトリックを使用してスクリプトスニペットを修正しました。要約すると、3つのバッチファイルがあり、1つは外部バックアップドライブが割り当てられている文字を見つけた後に他の2つを呼び出します。バックアップルーチンへの呼び出しが正常に機能するように、最初のファイルをプライマリ外部ドライブに残しましたが、2番目のファイルへの呼び出しにはアクティブなドライブの変更が必要でした。以下のコードは、どのように修正したかを示しています。

for %%b in (d e f g h i j k l m n o p q r s t u v w x y z) DO (
if exist "%%b:\Backup.cmd" %%b: & CALL "%%b:\Backup.cmd"
)
3
Louis

バッチファイル内のIFコマンドに関連する検索で返された結果でこの記事を見つけました。IFブロックは単一コマンドに限定されているという誤解を修正する機会に抵抗することはできませんでした。以下は、私がこの応答を作成しているマシンで毎日実行される実動Windows NTコマンドスクリプトの一部です。

    if "%COPYTOOL%" equ "R" (
    WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using RoboCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*"
    %TOOLPATH% %SRCEPATH% %DESTPATH% /copyall %RCLOGSTR% /m /np /r:0 /tee
    C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Robocopy] %TEMP%\%~n0.TMP %ERRORLEVEL%
) else (
    WWLOGGER.exe "%APPDATA%\WizardWrx\%~n0.LOG" "Using XCopy to make a backup of %USERPROFILE%\My Documents\Outlook Files\*"
    call %TOOLPATH%  "%USERPROFILE%\My Documents\Outlook Files\*" "%USERPROFILE%\My Documents\Outlook Files\_backups" /f /m /v /y
    C:\BIN\ExitCodeMapper.exe C:\BIN\ExitCodeMapper.INI[Xcopy] %TEMP%\%~n0.TMP %ERRORLEVEL%
)

おそらく、2行以上のブロックはWindows NTコマンドスクリプト(.CMDファイル)にのみ適用されます。これは、オールドスクールバッチ(.BAT)ファイルに制限されているアプリケーションの運用スクリプトディレクトリを検索すると、1つのコマンドブロックのみが明らかになったためです。アプリケーションが拡張メンテナンスになったため(サポートに積極的に関与していないことを意味します)、それが複数の行を必要としなかったからか、機能させることができなかったからかはわかりません。

とにかく、後者が当てはまる場合、簡単な回避策があります。複数の行を個別のバッチファイルまたはバッチファイルサブルーチンに移動します。後者は両方の種類のスクリプトで動作することを知っています。

1
David A. Gray

少し遅いかもしれませんが、それが役立つことを願っています:

@echo off 

if %ERRORLEVEL% == 0 (
msg * 1st line WORKS FINE rem You can relpace msg * with any othe operation...
goto Continue1
)
:Continue1
If exist "C:\Python31" (
msg * 2nd line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue2
)
:Continue2
If exist "C:\Python31\Lib\site-packages\PyQt4" (  
msg * 3th line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue3
)
:Continue3
msg * 4th line WORKS FINE rem You can relpace msg * with any othe operation...
    goto Continue4
)
:Continue4
msg * "Tutto a posto" rem You can relpace msg * with any othe operation...
pause
0
vinniejohnson