&& 在批处理/cmd 脚本中如何工作?

&& 在批处理/cmd 脚本中如何工作?

(我使用的是Win10 20H2)
我知道如果您有command A && command B,则command B仅在“成功完成”时执行command A,但究竟如何判断是否command A成功?

  • 我的第一个想法是它必须基于errorlevel,但事实并非如此,因为以下显示如果您在没有输入任何内容的情况下按下回车键,那么正如预期的那样,您将不会看到“成功”消息,并且 更改errorlevel1
    @echo off
    :loop
    set /p u_p= && echo success
    echo current errorlevel %errorlevel%
    goto loop
    
    errorlevel但是,如果您随后输入有效的输入,尽管剩余的为, 您仍会收到成功消息1,那么是什么触发了&&给出成功消息呢?

  • 有人建议可能需要延迟扩展,因为如果没有它,代码就会错误地报告当前的errorlevel,但是我已经尝试过,以及替换引用的行errorlevel,但我仍然得到输出以指示成功,尽管在输入空输入后errorlevel并非0所有后续输入都成功:
    if errorlevel 1 (echo current errorlevel geq 1) else (echo current errorlevel leq 0)
    

我相当肯定解释不是&& 被触发0 errorlevel,但代码导致错误报告errorlevel

答案1

我的第一个想法是它必须基于错误级别。

是的,但是你失踪了enabledelayedexpansion

这是必需的,因为您的脚本中实际上有一个循环,并且enabledelayedexpansion变量errorlevel在第一次设置后就不会改变。

使用setlocal enabledelayedexpansion将产生您所期望的行为:

@echo off
setlocal enabledelayedexpansion
:loop
set /p u_p= && echo success
echo current errorlevel %errorlevel%
goto loop
endlocal

启用延迟扩展

设置EnabledDelayedExpansion将导致每个变量在执行时而不是在解析时扩展。

来源Setlocal - 局部变量 - Windows CMD - SS64.com


进一步阅读

答案2

&&批处理文件中如何工作?

  • &&当前一个命令执行完毕后,将执行下一个命令returns 0
  • ||当前一个命令执行完毕后,将执行下一个命令returns non 0

几乎所有的应用程序和实用程序都会设置退出代码当他们完成/终止时:

你不会得到return 0有用的命令set /p,它没有效果准确等待&&return 0)执行下一个命令,特别是如果它在同一条线,无论是否setlocal启用

  • 成功就是定义返回一个%ERRORLEVEL% = 0;使用此语法读取和变量时必须小心SET,因为默认情况下变量一次扩展一行
  • 定义变量后执行命令而不检查该变量是否已定义,也不检查该值是否在所需的范围、布局、长度等内,这是不准确的。

无论输入是什么,无论是否给出,它都会结束Enter被按下,在这种情况下,你有errorlevel 0,如果Ctrl+C被使用,它将以这种方式结束errorlevel 1,在这个场景之外,没有太多的用处&&和/或||


  • 为了更精确,我建议检查变量中是否分配/假定任何值:
    if defined u_p (do) else (do instead)
    
    rem or ::
    
    if not "" == "%u_p%" (do) else (do instead)
    

  • 移植到您的代码时,我建议一些简单的方法:
    @echo off
    
    :loop
    set "u_p="
    
    set /p u_p= || goto loop
    if "%u_p%" == "" goto :loop
    
    rem ::  do next command here ... 
    

其他资源:

相关内容