web-dev-qa-db-ja.com

一時停止中にバッチスクリプトの実行を中断する

複雑で長時間実行されるバッチスクリプトを開発していますが、デバッグ時に小さな問題が発生しました。スクリプトのルートパスに対してコマンドラインウィンドウを開いているので、myscript.batと入力して、テストのためにスクリプトを起動できます。スクリプトの動作を監視するために、ステートメント間でPAUSEコマンドを使用しています。ただし、PAUSEコマンドの実行中にCTRL + Cを入力して実行をキャンセルすると、意図したとおりにスクリプトを中断するのではなく、実行を続行するためのキーとして解釈されることがわかりました。

コマンドウィンドウを強制終了/閉じることができることはわかっていますが、毎回新しいコマンドウィンドウで正しいパスに戻るのは少し面倒です。現在PAUSEにあるときに、バッチスクリプトの実行を簡単に適切に中断する方法はありますか?


編集: @dbenhamで示されているように、PAUSEは単純なスクリプトで正常に機能するようです。ただし、PAUSEイテレーション内にネストされた複数のFORステートメントがある場合、FORイテレーションの途中で中断することはできません-最後にのみ。この問題を示すサンプルスクリプトを次に示します。

@echo off

for /l %%y in (2008, 1, 2013) do (
    echo 1
    pause
    echo 2
    pause
    echo 3
    pause
    echo 4
    pause
    echo 5
    pause
)

最初の4つのPAUSEステートメントのいずれかを終了しようとすると、terminateコマンドが無視され、実行が続行されることがわかります。しかし、最後に到達すると、5番目のPAUSEまで、終了プロンプトが表示されます(以下の出力例では、すべてのプロンプトでCTRL + Cを押していました)。

Z:\>test
1
Press any key to continue . . .
2
Press any key to continue . . .
3
Press any key to continue . . .
4
Press any key to continue . . .
5
Press any key to continue . . .
Terminate batch job (Y/N)? y

この動作を防ぐ方法はありますか?

3
mellamokb

Win 7(32ビット)では問題なく動作します

これは簡単なテストスクリプトです

@echo off
echo Before
pause
echo After

<Ctrl-C>を押さずに上記を実行すると、次のようになります。

D:\test>test
Before
Press any key to continue . . .
After

D:\test>

「Pressanykey」プロンプトで<Ctrl-C>を押すと、次のようになります。

D:\test>test
Before
Press any key to continue . . .
Terminate batch job (Y/N)? y

D:\test>

編集:フォローアップ質問の解決策

ループする必要はありません。問題は、括弧で囲まれたコードブロックに存在します。ブロック全体が1回のパスで解析され、メモリから実行されます。

(
  echo Before 1
  pause
  echo Before 2
  pause
  echo After
)

PAUSEコマンドを使用した修正はないと思います。しかし、私はあなたが望むデバッグ機能を与えるべきである簡単な解決策を持っています。スクリプトを実行する前に、PAUSE環境変数がまだ定義されていないことを確認してください。

@echo off

:: ------------------------------------------------------
:: Include this block of code at the top of your script
::
setlocal
if not defined pause (
  set "pause=choice /m "........................Continue "&if errorlevel 2 exit"
  cmd /c ^""%~f0" %* ^"
  exit /b
)
:: ------------------------------------------------------


:: Now use %pause% instead of pause anywhere you want within your script
:: Press Y to continue, N to quit
:: The script will immediately terminate if you press N, even if in the
:: middle of a CALL

:: Here is a simple demonstration

call :sub1
exit /b

:sub1
call :sub2
exit /b

:sub2
for /l %%N in (1 1 3) do (
  echo ----- %%N ------
  echo Before 1
  %pause%
  echo Before 2
  %pause%
  echo After
)
exit /b
3
dbenham

括弧で囲まれたブロックのPAUSEの問題を克服する1つの方法は、サブルーチンを呼び出すことです。

@echo off
goto run

:pause
echo %*
pause >nul
exit /b

:run
(
  echo Before 1
  call :pause Please consider aborting with Ctrl+C
  echo Before 2
  call :pause Really consider aborting with Ctrl+C
  echo After
)

これにより、少なくともWindows 10の問題が解決され、PAUSEのカスタムメッセージが許可されます。

1
stevek_mcc