1

最近、set コマンドによって提供される /p オプションを使用して、Windows cmd.exe バッチ ファイルでユーザー入力を取得する簡単な方法を発見しました。しかし、奇妙な理由で、 set /p が if ステートメントの間で使用されるとトリッキーな動作をすることがわかりません。

まず、以下の「ScriptRunsOK.bat」コードという名前のバッチ ファイルを作成します。

@echo off
rem Gets a User Yes-No Choice 
set /p UserInput=Your Choice [Y/N]:
set UserChoice=%UserInput:~0,1%
if "%UserChoice%"=="y" set UserChoice=Y
if "%UserChoice%"=="Y" (
    echo You Accepted[%UserChoice%] typing %UserChoice%
) else (
    echo You Rejected[%UserChoice%] typing %UserChoice%
)
pause

次に、バッチ ファイル「ScriptRunsBAD.bat」を作成し、「User Input & Evaluation」コードを意図的に if ステートメントの間に含めます。次のようにコードします。

@echo off
rem Gets a User Yes-No Choice. Choice Nested in a IF Statement 
set DummyVar=OK
if "%DummyVar%"=="OK" (
    set /p UserInput=Your Chiuce [Y/N]:
    set UserChoice=%UserInput:~0,1%
    if "%UserChoice%"=="y" set UserChoice=Y
    if "%UserChoice%"=="Y" (
        echo You Accepted[%UserChoice%] typing %UserChoice%
    ) else (
        echo You Rejected[%UserChoice%] typing %UserChoice%
    )
)

pause

3番目に、「ScriptRunsOK.bat」をダブルクリックするか、コマンドラインから直接繰り返し実行します。実行するたびに正常に動作します。しかし、「ScriptRunsBAD.bat」で同じことを試してみると、私が見たようには機能せず、さらに、コマンドラインから実行すると、奇妙なことに、前の実行で入力されたユーザー入力が保持されます。

この動作を引き起こす "ScriptRunsBAD.bat" のコードは何ですか? if または複数行のステートメント内で set /p コマンドを使用する場合に考慮しなければならない追加の考慮事項はありますか?

4

1 に答える 1

1

良い。最後に、@melpomene と @Wimmel (ありがとう) によって投稿されたリンクの内容を読んだ後、問題を解決できました。簡単に言えば (詳細は投稿されたリンクをたどってください) cmd scripting evals (デフォルト) は、すべての行が解析されるときに変数を評価します (プログラマーであるときに期待される習慣的な動作ではありません)。解決されたスクリプトはSETLOCAL ENABLEDELAYEDEXPANSION、感嘆符を使用して参照された場合に変数を解析時ではなく実行時に展開できるようにする「遅延展開」を有効にするために使用します ( !UserInput:~0,1!およびを参照!UserChoice!)。

スクリプトは解決しました:

@echo off
rem Gets a User Yes-No Choice. Choice Nested in a IF Statement 
set DummyVar=OK
SETLOCAL ENABLEDELAYEDEXPANSION
if "%DummyVar%"=="OK" (
    set /p UserInput=Your Choice [Y/N]:
    set UserChoice=!UserInput:~0,1!
    if "!UserChoice!"=="y" set UserChoice=Y
    if "!UserChoice!"=="Y" (
        echo You Accepted[!UserChoice!] typing !UserInput!
    ) else (
        echo You Rejected[!UserChoice!] typing !UserInput!
    )
)
ENDLOCAL
于 2012-12-29T13:34:30.200 に答える