Batch file 导致批处理文件崩溃的IF语句

Batch file 导致批处理文件崩溃的IF语句,batch-file,Batch File,G'Day,我正在创建一个程序,告诉您是否连接到internet,该程序的一个关键部分是以下if语句 ping google.com >nul if %errorlevel% NEQ 0 goto no rem "no" is not showed in this code example if %errorlevel% EQU 0 goto yes :yes if %a% EQU 1 ( goto Begin ) else ( cls color a

G'Day,我正在创建一个程序,告诉您是否连接到internet,该程序的一个关键部分是以下if语句

ping google.com >nul

if %errorlevel% NEQ 0 goto no
rem "no" is not showed in this code example
if %errorlevel% EQU 0 goto yes

:yes
if %a% EQU 1 (
    goto Begin
) else (
    cls
    color a
    echo Connected
    set a=1
)
在此上下文中,变量“a”定义了连通性

例如,这段代码循环,所以如果“a”等于“1”,我们知道我们已经连接了,并且这段代码不是必需的,所以我们应该循环回ping命令。当“a”为“0”时,我们知道以前没有连接到internet

这可能很难接受,所以如果你对此有疑问,请在下面提问,因为我想不出更好的解释

除此之外(正如我在标题中所说)作为批处理文件不断崩溃(意外退出)。我找不到这个问题的答案,这让我发疯。(链接到所有代码)

多谢
-R

如果在到达If命令行之前未初始化名为
a
的环境变量,则命令行将扩展为:

if EQU 1 (
这将导致由于语法错误而退出批处理文件处理的执行

Windows命令解释器在批处理文件执行时不会崩溃。它清楚地指出了语法错误,因为从命令提示符窗口中运行批处理文件时可以看到语法错误(
cmd.exe
start with option
/K
to在完成批处理文件或控制台应用程序的执行后保持控制台窗口打开),而不是双击批处理文件(
cmd.exe
以选项
/C
启动,以在完成批处理文件或控制台应用程序的执行后关闭窗口)

解决办法是:

  • 使用更好的环境变量名
  • 初始化批处理文件顶部的环境变量
  • 使用更快的字符串比较而不是数字比较,因为环境变量始终为string类型,而不是integer类型。因此,整数比较要求Windows命令解释器必须将环境变量的字符串值以及字符串
    1
    转换为整数,以便执行整数比较姆帕里森
  • 以下是您重新编写的批处理代码:

    @echo off
    set "ConnectionState=0"
    
    rem Send only 1 echo request with a timeout of 2000 ms to google.com.
    %SystemRoot%\System32\ping.exe -n 1 -w 2000 google.com >nul 2>nul
    if errorlevel 1 goto NoConnection
    
    if "%ConnectionState%" == "1" goto Begin
    cls
    color a
    echo Connected
    set "ConnectionState=1"
    goto :EOF
    
    :NoConnection
    echo There is no connection to world wide web.
    
    :Begin
    echo There is a connection to world wide web.
    
    建议使用完整路径和文件扩展名指定控制台应用程序,如
    ping
    ,以使批处理文件独立于环境变量pathPATHEXT

    建议只ping
    google.com
    一次,并指定超时时间,而不是默认情况下的3次

    建议不要使用
    %ERRORLEVEL%
    (立即扩展)或
    !ERRORLEVEL!
    (延迟扩展)但使用
    如果errorlevel 1…
    表示上一个应用程序或命令的退出代码大于或等于1,或者使用
    如果不是errorlevel 1…
    表示上一个应用程序或命令的退出代码小于1,对于所有标准Windows命令和可执行文件而言等于0。(应用程序不应以负值退出。无论是在Windows上,还是在Linux或Mac上,都可以这样做,但不建议这样做。)另请参阅非常旧的Microsoft支持文章,该文章对MS-DOS到最新版本的Windows 10都是100%正确的

    字符串比较中包含了IF命令行上的双引号。这使得环境变量
    ConnectionState
    在本例中,当命令行扩展为:

    if "" == "1" goto Begin
    
    此命令行是正确的,因为根据需要,equal运算符的左侧和右侧各有一个参数。
    equal
    也可以用来代替
    ==
    ,但需要启用的命令扩展,默认情况下,这些扩展当然是启用的

    要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读为每个命令显示的所有帮助页面

    • cls/?
    • color/?
    • echo/?
    • goto/?
    • 如果/?
    • ping/?
    • rem/?
    • 设置/?
    另请阅读Microsoft关于的文章,以了解
    >nul
    2>nul
    的解释

    而在执行过程中通过语法检查由
    cmd.exe
    解释的批脚本不是一个程序,该程序的源代码由编译器编译为本机CPU指令,在编译状态下进行语法检查。不可能编译引用v变量完全没有定义。(但编译一个程序时,如果定义的变量在求值之前没有初始化,则可能导致未定义的行为或异常。)


    有关将值与IF进行比较的额外信息

    IFequal运算符
    ==
    总是导致字符串比较,而运算符
    equal
    首先总是尝试整数比较,如果不可能,也会执行字符串比较,这可以通过以下方法证明:

    @echo off
    if 00 == 0  (echo 00 is equal 0 on using ==)  else (echo 00 is different 0 on using ==)
    if 00 EQU 0 (echo 00 is equal 0 on using EQU) else (echo 00 is different 0 on using EQU)
    
    执行时的输出为:

    00 is different 0 on using ==
    00 is equal 0 on using EQU
    
    在批处理代码中,如果适当的代码保证环境变量
    ConnectionState
    总是在执行if命令行之前使用值
    0
    1
    定义,则可以安全地删除参数
    %ConnectionState%
    0
    周围的双引号通过Windows命令解释器逐行处理批处理文件

    我添加双引号是为了让每个人都清楚,字符串是比较的,因为两个参数的双引号也是比较的

    IF
    =
    运算符可以在C中编码,例如
    @echo off
    equ.exe \"08\" \"08\"
    equ.exe 08 8
    equ.exe 14 14
    equ.exe 014 014
    equ.exe 0x14 0x14
    equ.exe 0x14 20
    equ.exe 0x14 \"20\"
    
    "08" EQU "08"
    The strings are equal.
    08 EQU 8
    The strings are different.
    14 EQU 14
    The integers 14 and 14 are equal.
    014 EQU 014
    The integers 12 and 12 are equal.
    0x14 EQU 0x14
    The integers 20 and 20 are equal.
    0x14 EQU 20
    The integers 20 and 20 are equal.
    0x14 EQU "20"
    The strings are different.