(我使用的是Win10 20H2)
我知道如果您有command A && command B
,则command B
仅在“成功完成”时执行command A
,但究竟如何判断是否command A
成功?
- 我的第一个想法是它必须基于
errorlevel
,但事实并非如此,因为以下显示如果您在没有输入任何内容的情况下按下回车键,那么正如预期的那样,您将不会看到“成功”消息,并且 更改errorlevel
为1
:@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 ...
其他资源:
Set /?
ErrorLevel
- 重定向
|
,<
,>
,2>
, ETC。
- 条件执行
- Windows 命令解释器如何
cmd.exe
解析脚本