找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 9350|回复: 15

[其他] CMD脚本中,不启用延迟扩展,怎样取得IF复合语句内正确的ErrorLevel值?谢谢!

[复制链接]
发表于 2025-7-11 19:34:48 | 显示全部楼层 |阅读模式
本帖最后由 Shuye 于 2025-7-11 20:15 编辑

不启用延迟扩展

Set "Tar=3"
IF Defined Tar (
   del Abc.abc
   Echo ErrorLevel===%ErrorLevel%
)

Abc.abc是不存在的,这时的ErrorLevel值应该是1,输出却是0。
怎样才能得到ErrorLevel===1?
谢谢啦!
发表于 2025-7-11 19:47:30 | 显示全部楼层
逃脱预处理Call echo %%errorlevel%%
判断if errorlevel 1 echo error
 楼主| 发表于 2025-7-11 19:56:51 | 显示全部楼层
逃脱预处理Call echo %%errorlevel%%
判断if errorlevel 1 echo error
77七 发表于 2025-7-11 19:47



谢谢 77七 兄!

Set "Tar=3"
IF Defined Tar (
   del Abc.abc
   Call echo %%errorlevel%%
)

输出还是0。
发表于 2025-7-11 20:25:10 | 显示全部楼层
回复 3# Shuye
应该是del 命令的设定问题。初步试了下,只有非法文件名,errorlevel=123,其余都是0。
 楼主| 发表于 2025-7-11 20:29:08 | 显示全部楼层
回复  Shuye
应该是del 命令的设定问题。初步试了下,只有非法文件名,errorlevel=123,其余都是0。
77七 发表于 2025-7-11 20:25



谢谢 77七 兄!

输出的这个0,估计是IF体外, Set "Tar=3" 的返回值。
发表于 2025-7-11 20:43:21 | 显示全部楼层
本帖最后由 aloha20200628 于 2025-7-11 21:10 编辑

回复 1# Shuye

可参考英文老帖(https://stackoverflow.com/questi ... s/34987886#34987886)一共挂了5张列表说明 CMD 常用命令的错误代码值(errorlevel),其中 del 只有两种结果,一是无参数(归于 '语法错误')或参数错误(归于 '无效开关')时会将 errorlevel 设为非零值,其余(无论目标文件存在与否)皆为零 ...
发表于 2025-7-11 20:46:49 | 显示全部楼层
回复 5# Shuye


   简单测试
  1. @echo off
  2. rem del失败 改变返回值
  3. md "|"
  4. echo %errorlevel%
  5. del "abc.abc"
  6. echo %errorlevel%

  7. rem del成功 改变返回值
  8. echo=
  9. cd.>abc.abc
  10. md "|"
  11. echo %errorlevel%
  12. del "abc.abc"
  13. echo %errorlevel%
  14. pause
复制代码
 楼主| 发表于 2025-7-11 23:40:40 | 显示全部楼层
本帖最后由 Shuye 于 2025-7-12 18:13 编辑

这个估计与 del 无关,应该是 IF 惹的祸。
我们换个命令,copy,其中的 Abc.abc 是不存在的。

Set "Tar=3"
copy Abc.abc Abc22.abc
Echo ErrorLevel22===%ErrorLevel%

输出:ErrorLevel22===1,这个是正确的,应该是 copy 的返回值。


再将 copy 放入 IF 体内:

Set "Tar=3"
IF Defined Tar (
   copy Abc.abc Abc22.abc
   Echo ErrorLevel33===%ErrorLevel%
)

输出:ErrorLevel33===0,这个是错的,它不是 copy 的返回值,应该是 Set "Tar=3" 的返回值。

也就是说,IF 体内的 %ErrorLevel%,不是 IF 体内命令的返回值,而是 IF 体之前最后一条命令的返回值。

IF 体内,怎样取得正确的 %ErrorLevel% ?
前提是不启用延迟扩展。如果启用延迟扩展,!ErrorLevel!值都是正确的。
发表于 2025-7-12 11:55:26 | 显示全部楼层
本帖最后由 aloha20200628 于 2025-7-12 15:40 编辑

回复 8# Shuye

  首先这是由于 '预处理' 的结果》即复合语块(被圆括号包裹的一组代码或被 & 链接的一组代码)被解释执行前会对其内的所有 %var% 变量预先赋值。因此,8楼代码 if 体内的 %errorlevel% 总是 if 之前的取值。
  其次再来谈 if 体内有效采用错误返回值的方法》
  一。为直接规避预处理拦截,采用 !errorlevel! 肯定是有效的。
  二。采用保留关键词 errorlevel 而非 !errorlevel! 变量,示例代码如下。
  三。采用 &&和 || 运算符,示例如下。
  但如一些老帖中所述,被多年的实用结果验证是第一种方法的灵活性和可靠性更好,因而被优先推荐...

  备注》从6楼英文老帖挂表中查有 copy 命令返回值类型,当目标文件不存在或参数错误其返回值=1,其余均返回零。
方法二

  1. @echo off & set "tar=3"
  2. if defined tar (
  3.    copy /y 1.txt 2.txt>nul 2>nul
  4.    if errorlevel 1 (echo,复制失败) else echo,复制成功
  5. )
  6. pause&exit/b
复制代码
方法三

  1. @echo off & set "tar=3"
  2. if defined tar (
  3.    copy /y 1.txt 2.txt>nul&&echo,复制成功||echo,复制失败
  4. )
  5. pause&exit/b
复制代码
发表于 2025-7-12 14:56:19 | 显示全部楼层
本帖最后由 77七 于 2025-7-12 15:07 编辑

1楼的方法获取的的确是if 外的errorlevel,这个值应该是脚本的初始值,echo、set 成功均不会改变errorlevel值。
2楼已经说明了方法。3楼代码正确,获取的是del 命令的errorlevel值,但是由于del本身设定问题导致errorlevel仍为0,4楼已经说明。

删除前必须有文件,删除后文件消失,可以试试以下代码

  1. @echo off
  2. chcp 936 >nul
  3. del "#" 2>&1 | find /v "删除文件 -"
  4. if errorlevel 1 (
  5.         echo 删除成功
  6. ) else (
  7.         echo 存在删除失败的文件(或属性问题 或文件被占用^) 或文件不存在(或非法文件名^) 或参数错误
  8. )
  9. pause
复制代码
 楼主| 发表于 2025-7-12 18:18:29 | 显示全部楼层
谢谢 aloha20200628 兄、77七 兄!

类似于 del、copy 的内部、外部命令很多,
有没有一种通用的方法?
就像 !ErrorLevel! 那样的。
发表于 2025-7-12 19:30:44 | 显示全部楼层
回复 11# Shuye

其实都写在9楼了。再问就说要楼主回答了 - 为何不想采用 !errorlevel! 呢?
发表于 2025-7-12 20:18:08 | 显示全部楼层
看来盖了好几楼都是无效沟通。
至少在我的实际使用中,if errorlevel 1和 if !errorlevel! geq 1 是没区别的。
这种用法从2楼就开始提及,楼主却还在反复追问...
发表于 2025-7-13 09:51:47 | 显示全部楼层
回复 8# Shuye


输出:ErrorLevel33===0,这个是错的,它不是 copy 的返回值,应该是 Set "Tar=3" 的返回值。

你的猜测是错误的。
并非每个命令执行完毕之后都会改变errorlevel的值,具体信息可以仔细阅读6楼链接。
发表于 2025-7-13 09:54:50 | 显示全部楼层
批处理各命令错误返回值errorlevel一览
http://bbs.bathome.net/thread-3603-1-1.html

errorlevel的范围是[-2147483648,2147483647]
https://stackoverflow.com/questi ... egative-error-codes

不同的命令设置errorlevel值是不一样的
https://stackoverflow.com/questi ... s/34987886#34987886

批处理中errorlevel的几点猜测
http://bbs.bathome.net/thread-14277-1-1.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 06:27 , Processed in 0.024103 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表