如果语句(此时是意外的

时间:2019-09-10 14:49:37

标签: windows batch-file if-statement cmd

我有一个捆绑的if语句,该语句检查是否安装了Java,以及我是否在大学或在家中,它是一大段代码的一部分,但不能单独工作,这对任何帮助都不会很大赞赏

三重检查后,我拥有正确的方括号和等号,并确保没有出现明显的错误,因此我对哪里出了问题感到困惑

if exist 'C:\Temporary Workspace' (set installtype=College)
where java >nul 2>nul
pause
if %errorlevel%==1 (
    if %installtype%==College (
    goto :college
    ) else (
        set /P javaboolean=Java was not found is java installed? (Y/N)
        if %javaboolean%==Y (
            echo Please enter the path to java.exe
            set /P javalocation=e.g. C:\Program Files\Common Files\Oracle\Java\javapath\java.exe
        ) 
    )
)
pause
exit
:college
echo success for college detection
pause

错误消息和运行时间:


D:\Batch Testing>echo Checking Location...
Checking Location...

D:\Batch Testing>if exist 'C:\Temporary Workspace' (set installtype=College)

D:\Batch Testing>where java  1>nul 2>nul

D:\Batch Testing>pause
Press any key to continue . . .
( was unexpected at this time.


我希望该输出确实存在,因为目录确实存在

2 个答案:

答案 0 :(得分:3)

您需要稍微更改if

第一个可以更改为

if exist "C:\Temporary Workspace" set installtype=College

请注意,单撇号不是Windows cmd中的有效引号。而且您可以删除括号,因为不需要它们。

第二个可以写为

if errorlevel 1 (

因为errorlevel不是%errorlevel%(有关详细说明,请阅读https://devblogs.microsoft.com/oldnewthing/20080926-00/?p=20743

最后一个可能是

if .%installtype%==.College (

因为installtype为空,if指令没有意义,并且会产生语法错误;插入两个.可以避免这种情况。

...,并且,作为奖励,您可能希望在比较时考虑使用if /i忽略大小写,因此Collegecollege,{{1} }甚至COLLEGE都可以匹配。

答案 1 :(得分:0)

好吧,您的代码中有几个问题。线

if exist 'C:\Temporary Workspace' (set installtype=College)

将永远不会设置变量installtype,因为这会检查'C:\Temporary是否存在,而不会,因为撇号'只是Windows命令提示符{{1 }}。要使其正常工作,必须使用引号cmd

"

结尾的if exist "C:\Temporary Workspace\" (set "installtype=College") 允许条件检查是否存在名为\的目录,而不是该名称的文件。

请注意,我在这里使用了引用的Temporary Workspace语法,通常建议这样做,因为它可以保护特殊字符。


条件

set

将返回语法错误,因为之前未设置变量 if %installtype%==College ( (由于使用的语法错误)。为避免使用空变量带来麻烦,请同时引用两个比较表达式:

installtype

这在this thread中也有描述。


命令

    if "%installtype%"=="College" (
在带括号的代码块中,

将失败,因为 set /P javaboolean=Java was not found is java installed? (Y/N) 会无意中识别)并将其关闭在不希望的位置。再次使用引号解决该问题:

cmd

或:

        set /P javaboolean="Java was not found is java installed? (Y/N)"

但是,情况

        set /P "javaboolean=Java was not found is java installed? (Y/N)"

仍然会失败,因为在同一代码块中设置了查询变量 if %javaboolean%==Y ( ,因此返回的值是解析整个块时出现的值,很可能是空字符串。为了克服这个问题,您必须应用delayed variable expansion

将其放置在某个位置以启用延迟扩展:

javaboolean

然后用感叹号 setlocal EnableDelayedExpansion 替换%-符号(如您所见,我再次在此处应用引号):

!

然后将其放置在某处以结束 if "!javaboolean!"=="Y" ( 引入的环境本地化:

setlocal

关于 endlocal 之后的所有环境更改(变量,当前目录)在setlocal之后丢失,并且endlocal之前的状态恢复。

this question中也描述了类似的问题,并由this answer解决。


考虑使用choice command而不是setlocal来决定是否使用,ErrorLevel不允许输入其他任何内容:

set /P

代替

rem /* The default choices are `Y` and `N`;
rem    `choice` sets `ErrorLevel` to `1` when pressing `Y` and to `2` when pressing `N`: */
choice /M "Java was not found is java installed"
rem // The following means: if ErrorLevel >= 1 and if ErrorLevel < 2:
if ErrorLevel 1 if not ErrorLevel 2 (echo Yes has been chosen.)

您应该使用

exit

仅终止批处理脚本,但使托管exit /B 实例保持活动状态。当您从命令提示符窗口执行批处理文件时,而不是在资源管理器中双击其图标时,这特别有用,因为您可以随后查看控制台输出。


代替字符串比较

cmd

您还可以像进行真正的数值比较

if %errorlevel%==1 (

或者,如果您可以接受condition execution operators也大于1的条件为真,

if %errorlevel% equ 1 (

或者,您甚至可以使用exit code来查询{{3}}:

if ErrorLevel 1 (

最后,这是固定脚本:

  1. 基于您的代码:

    where java > nul 2>&1 && (
        rem // The code here is executed when `where` succeeds.
    ) || (
        rem // The code here is executed when `where` fails.
    )
    
  2. 使用条件执行(if exist "C:\Temporary Workspace\" (set "installtype=College") where java > nul 2>&1 pause if ErrorLevel 1 ( if "%installtype%"=="College" ( goto :college ) else ( set /P javaboolean="Java was not found is java installed? (Y/N) " setlocal EnableDelayedExpansion if "!javaboolean!"=="Y" ( endlocal echo Please enter the path to java.exe set /P javalocation="e.g. C:\Program Files\Common Files\Oracle\Java\javapath\java.exe " ) else endlocal ) ) pause exit /B :college echo success for college detection pause )和||命令的变体形式:

    choice