Windows批处理文件中的If语句

4

我一直被这个愚蠢的if语句困扰着,无论我做什么,都不能让if语句跳转到正确的标签。

  1. 输入“y”可以正常工作,命令提示符会停在“START DEPLOY”处。
  2. 但是,如果我输入“n”,命令提示符会打印“START DEPLOY”,然后直接到结尾,而不是直接跳转到取消标签。

你能帮忙吗?

:getConfirmation
set /p confirmDeploy =Confirm deployment of code [y/n] ?: 
if "%confirmDeploy%"=="y". goto deployCode
if "%confirmDeploy%"=="n". goto cancelDeploy

:deployCode
ECHO START DEPLOY
goto end

:cancelDeploy
ECHO DEPLOY CANCELLED
goto end

旁注 - end 标签已定义吗?还是你打算使用 goto :eof (相当于 exit /b)? - dbenham
已经定义好了,感谢您的询问。我必须在if语句中使用“:”来标记名称,以使其正常工作。 - c14kaa
5个回答

16

试试这个:

@echo off
:getConfirmation
set /p confirmDeploy=Confirm deployment of code [y/n] ?: 
if %confirmDeploy%==y goto :deployCode
if %confirmDeploy%==n goto :cancelDeploy

:deployCode
ECHO START DEPLOY
goto end

:cancelDeploy
ECHO DEPLOY CANCELLED
goto end

4
最好用引号将其括起来 if "%confirmDeploy%"=="y",否则它会因为空输入或特殊字符(如&|<space><TAB>)而失败。 - jeb
请注意,我必须像@Bali在他的示例中所做的那样删除“set /p confirmDeploy”后面的空格。如果我保留了那个空格,它就不会将用户输入放入我的变量中。 - Nick DeVore

3
如果我们忽略必须输入 y 或 n(由于 if 比较中的 .),则没有人注意到 c14kaa 脚本的实际问题(除了 Nick DeVore,但他没有说原因)。原始脚本有一行:
set /p confirmDeploy =Confirm deployment of code [y/n] ?:
Nick 提到这不会将响应放入变量中。那是因为它把响应放入“confirmDeploy”(空格是变量名的一部分,这是 cmd 输入解析的另一个怪癖)。因此,当 c14kaa 使用 %confirmDeploy% 时,除非该变量在其他地方设置,否则它将扩展为 %confirmDeploy%(即被字面上采用)。我只能假设 c14kaa 已经关闭了回显,因为 confirmDeploy 没有替换(或包含其他内容而不是 y 或 n)将是一个很大的线索。它也将揭示 if 语句中的问题。
至于其他建议,最好将变量括在""中(因此需要匹配字符串),以防止变量为空时出现语法错误(生成语句“if == y”,jeb 的意思是“失败”),goto 中标签名称前面的 : 将被忽略,在 John 的版本中 /I 后面需要有一个空格(尽管 if 命令只有一个选项,但某些命令有许多选项,它们可以组合在一起,例如“findstr /ivn ...”,因此空格标记列表的结尾)。
我唯一想说的是,c14kaa 假设用户总是输入正确的响应(y 或 n),否则脚本将“掉入”到 :deployCode 部分(可能不是理想的默认行为)。这解释了 Matt 建议的响应(echo bad input)。由于响应被放入 confirmDeploy<space> 中,这意味着两个测试(使用没有空格的 confirmDeploy)都失败了。
综上所述,我们得到了 Reny 的版本(加上一些说明)。

1

你已经走上了正确的道路,只需要清理语法和空格错误。这将起作用:

@echo off  
:getConfirmation  
set /p confirmDeploy=Confirm deployment of code [y/n] ?:   
if /I "%confirmDeploy%"=="y" goto deployCode  
if /I "%confirmDeploy%"=="n" goto cancelDeploy  
REM added goto getConfirmation in case of invalid responses  
goto getConfirmation

:deployCode  
ECHO START DEPLOY  
goto end  

:cancelDeploy  
ECHO DEPLOY CANCELLED  
goto end

0

也试试这个:

@echo off
:getConfirmation
set /p confirmDeploy=Confirm deployment of code [y/n] ?: 
if /I%confirmDeploy%==y goto :deployCode
if /I%confirmDeploy%==n goto :cancelDeploy

:deployCode
ECHO START DEPLOY
goto end

:cancelDeploy
ECHO DEPLOY CANCELLED
goto end

/I参数使其不区分大小写。

0
问题在于你的两个测试都不起作用。你正在检查用户输入类似于y.n.之类的内容(但我认为实际上你无法输入任何匹配的内容)。
尝试使用:
if "%confirmDeploy%".=="y". goto deployCode
if "%confirmDeploy%".=="n". goto cancelDeploy
echo bad input
goto getConfirmation

...

很抱歉,这好像不起作用。我得到了以下信息:确认部署代码 [y/n] ?: y 无效输入 确认部署代码 [y/n] ?: n 无效输入 - c14kaa
我正在使用XP,我知道这可能会有所不同。 - c14kaa
你有没有注意到我发布的 if 行不是你所拥有的那些? - Mat
1
那应该可以工作,不过如果你在IF语句中添加/I选项可能会更加用户友好。另外,为什么不直接从两侧删除点呢? - dbenham
谢谢您的帮助,Mat。Bali C的例子对我很有用,去掉引号并在标签名称前添加冒号! - c14kaa
如果您在提示符处输入空格或多个单词,Bali的答案将会导致错误。 - Mat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接