带有用户输入的Windows批处理if语句
bat应将用户输入与值进行比较。当我用1或2的输入测试它时,如果“%choice%”=“1”,它不会进入带有用户输入的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
内部
以下是批处理文件:
@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
进行此类用户提示,仅使用文件名或使用完全限定的文件名,以实现最大的执行安全性。感谢您提供的详细信息!