带有用户输入的Windows批处理if语句

带有用户输入的Windows批处理if语句,windows,batch-file,if-statement,cmd,Windows,Batch File,If Statement,Cmd,bat应将用户输入与值进行比较。当我用1或2的输入测试它时,如果“%choice%”=“1”,它不会进入内部 以下是批处理文件: @echo off rem ... IF [%$ecbId%] == [] ( echo Enter '1' to blabla echo Enter '2' to blabla echo Enter anything to abort set /p choice="Type input: " IF "%choice%"=="1

bat应将用户输入与值进行比较。当我用1或2的输入测试它时,如果“%choice%”=“1”,它不会进入
内部

以下是批处理文件:

@echo off
rem ...
IF [%$ecbId%] == [] (
    echo Enter '1' to blabla
    echo Enter '2' to blabla
    echo Enter anything to abort
    set /p choice="Type input: "
    IF "%choice%"=="1" (
        echo toto1
        rem save into property file
        echo currentMaster=%ecb%>> MDC.properties
        echo masterDcName=ECBDC>> MDC.properties
        echo currentClone=%bdf%>> MDC.properties
        echo cloneDcName=BDFDC>> MDC.properties
    )
    IF "%choice%"=="2" (
        echo toto2
        rem save into property file
        echo currentMaster=%bdf%>> MDC.properties
        echo masterDcName=BDFDC>> MDC.properties
        echo currentClone=%ecb%>> MDC.properties
        echo cloneDcName=ECBDC>> MDC.properties
    )
    IF NOT "%choice%"=="1" (
        echo toto3
        IF NOT "%choice%"=="2" (
            echo toto4
            echo Unknown input ... Aborting script
            exit /b 400
        )
    )
)
命令输出:

Enter '1' to blabla
Enter '2' to blabla
Enter anything to abort
Type input: 1
toto3
toto4
Unknown input ... Aborting script

如果“%choice%”=“1”
条件,为什么它没有进入
内部?

以下代码可能可以帮助您

@echo off
echo Enter '1' to blabla
echo Enter '2' to blabla
echo Enter anything to abort
set /p choice="Type input: "

IF "%choice%"=="1" goto echoto1         

rem enter anything here you want it to do if variable is not met

:echoto1
rem start's here if the variable was met
echo toto1
@echo currentMaster=%ecb%>> MDC.properties
@echo masterDcName=ECBDC>> MDC.properties
@echo currentClone=%bdf%>> MDC.properties
@echo cloneDcName=BDFDC>> MDC.properties

以下是工作批次代码:

@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem ...
if "%$ecbId%" == "" (
    echo Enter '1' to blabla
    echo Enter '2' to blabla
    echo Enter anything else to abort.
    echo/
    set "UserChoice=abort"
    set /P "UserChoice=Type input: "
    if "!UserChoice!" == "1" (
        echo toto1
        rem save into property file
        >>MDC.properties echo currentMaster=%ecb%
        >>MDC.properties echo masterDcName=ECBDC
        >>MDC.properties echo currentClone=%bdf%
        >>MDC.properties echo cloneDcName=BDFDC
    )
    if "!UserChoice!" == "2" (
        echo toto2
        rem save into property file
        >>MDC.properties echo currentMaster=%bdf%
        >>MDC.properties echo masterDcName=BDFDC
        >>MDC.properties echo currentClone=%ecb%
        >>MDC.propertiesecho cloneDcName=ECBDC
    )
    if not "!UserChoice!" == "1" (
        echo toto3
        if not "!UserChoice!" == "2" (
            echo toto4
            echo Unknown input ... Aborting script
            endlocal
            exit /B 400
        )
    )
)
endlocal
使用命令
setlocal EnableExtensions EnableDelayedExpansion
在批处理文件顶部启用。命令SETLOCAL不仅启用延迟扩展,还将整个命令过程环境保存在堆栈上,如我在上的回答中详细解释的那样。在执行命令ENDLOCAL时,命令处理环境将从堆栈中恢复,当未显式执行
ENDLOCAL
时,Windows命令处理器也将在退出批处理文件处理时执行此操作

在命令块中设置或修改的所有环境变量(以
开始,以匹配的
结束)
以及在同一命令块中引用的)必须使用延迟扩展来引用

当Windows command processor到达第四行时,整个命令块直到最后一行被解析和预处理,然后才计算IF条件。在这个预处理步骤中,从第4行到第36行,用百分号引用的所有环境变量在整个块中展开

这意味着在对第4行的IF条件进行评估之前,所有出现的
%ecb%
%bdf%
都会被环境变量
ecb
bdf
的当前值所取代,就像IF条件本身中的
%ecbId%
一样

只有环境变量
UserChoice
在解析/预处理整个块时不会展开,因为此环境变量是使用延迟展开引用的

因此,可以为环境变量
UserChoice
指定一个默认值,如
abort
,以防批量用户点击,只需返回或输入,而不输入任何内容

由于对环境变量
UserChoice
使用延迟扩展,用户输入的字符串在解析/预处理阶段永远不会展开。
UserChoice
的当前字符串值总是在计算每个IF条件时解释

Windows命令处理器的这种行为可以通过

  • 从批处理文件的第一行删除
    @echo off
  • 打开命令提示窗口
  • 如果当前目录不是批处理文件的目录,则在命令提示窗口中通过输入具有完整路径的批处理文件的名称来运行批处理文件
  • Windows命令处理器现在总是在解析后输出行或命令块,然后才真正执行。因此可以看出,在达到第一个IF条件时,整个命令块已经过预处理,即分别用环境变量中的适当字符串替换所有出现的
    %…%
    ,如果尚未定义参考环境变量,则不执行任何操作。可以看出,当整个命令块中的下一个命令行由Windows命令解释器执行时,
    %ecb%
    %bdf%
    的值将不再被修改

    更紧凑的是:

    @echo off
    setlocal EnableExtensions EnableDelayedExpansion
    rem ...
    if "%$ecbId%" == "" (
        echo Enter '1' to blabla
        echo Enter '2' to blabla
        echo Enter anything else to abort.
        echo/
        set "UserChoice=abort"
        set /P "UserChoice=Type input: "
        if "!UserChoice!" == "1" (
            echo toto1
            rem save into property file
            >>MDC.properties echo currentMaster=%ecb%
            >>MDC.properties echo masterDcName=ECBDC
            >>MDC.properties echo currentClone=%bdf%
            >>MDC.properties echo cloneDcName=BDFDC
        ) else if "!UserChoice!" == "2" (
            echo toto2
            rem save into property file
            >>MDC.properties echo currentMaster=%bdf%
            >>MDC.properties echo masterDcName=BDFDC
            >>MDC.properties echo currentClone=%ecb%
            >>MDC.properties echo cloneDcName=ECBDC
        ) else (
            echo Unknown input ... Aborting script
            endlocal
            exit /B 400
        )
    )
    endlocal
    
    另一种解决方案是使用命令
    choice
    ,该命令自Windows Vista以来默认可用。它的优点是用户只需按三个键中的一个。在这种情况下,不需要延迟环境变量展开,因为
    选项
    的退出值取决于分配给环境变量
    errorlevel
    的按键,即使在命令块内也可以在不延迟展开的情况下对其进行评估

    @echo off
    rem ...
    if "%$ecbId%" == "" (
        echo Enter '1' to blabla
        echo Enter '2' to blabla
        echo Enter 'A' to abort.
        echo/
        %SystemRoot%\System32\choice.exe /C 12A /N /M "Type input:"
        if errorlevel 3 (
            echo Aborting script
            exit /B 400
        ) else if errorlevel 2 (
            echo toto2
            rem save into property file
            >>MDC.properties echo currentMaster=%bdf%
            >>MDC.properties echo masterDcName=BDFDC
            >>MDC.properties echo currentClone=%ecb%
            >>MDC.properties echo cloneDcName=ECBDC
        ) else (
            echo toto1
            rem save into property file
            >>MDC.properties echo currentMaster=%ecb%
            >>MDC.properties echo masterDcName=ECBDC
            >>MDC.properties echo currentClone=%bdf%
            >>MDC.properties echo cloneDcName=BDFDC
        )
    )
    
    由于字符
    1
    被指定为选项
    /C
    后的第一个字符,用户必须按1,导致
    选择
    带值退出
    1
    ,或按2键让
    选择
    带值退出,或按A键(不区分大小写)在选项
    /C
    之后的下一个参数字符串中,将值为
    3
    choice
    作为字符
    A
    的退出指定为第三个字符。在额外确认后,还可以按Ctrl+C退出批处理文件处理。
    choice
    会忽略所有其他按键,并产生铃声输出,通知用户按键错误


    现在最好使用命令
    choice
    进行此类用户提示,仅使用文件名或使用完全限定的文件名,以实现最大的执行安全性。

    感谢您提供的详细信息!