del
and ErrorLevel
?
The del
命令不设置ErrorLevel
只要给定的参数有效,它甚至会重置ErrorLevel
to 0
在这种情况下(至少对于 Windows 7)。
del
修改ErrorLevel
仅在提供无效开关的情况下(del /X
sets ErrorLevel
to 1
),根本没有指定任何参数(del
sets ErrorLevel
to 1
太),或者给出了不正确的文件路径(del :
sets ErrorLevel
to 123
),至少对于 Windows 7 而言。
可能的解决方法
一个可能的解决方法是捕获STDERR
的输出del
,因为如果发生删除错误,相关消息(Could Not Find [...]
, Access is denied.
, The process cannot access the file because it is being used by another process.
)写在那里。这样可能看起来像:
for /F "tokens=*" %%# in ('del /F /Q "\path\to\the\file_s.txt" 2^>^&1 1^> nul') do (2> nul set =)
要直接在命令提示符中使用代码而不是在批处理文件中,请编写%#
代替%%#
.
如果您不想删除只读文件,请删除/F
来自del
命令行;
如果您确实需要提示(以防通配符?
and/or *
存在于文件路径中),删除/Q
.
代码解释
这会执行命令行del /F /Q "\path\to\the\file_s.txt"
。按部分2>&1 1> nul
,命令输出在STDOUT
将被解雇,其STDERR
输出将被重定向,以便for /F
收到它。
如果删除成功的话del
不生成STDERR
输出,因此for /F
循环不会迭代,因为没有什么可解析的。请注意ErrorLevel
在这种情况下不会被重置,其值保持不变。
If for /F
收到任何STDERR
输出从del
命令行,执行循环体内的命令,即set =
;这是无效的语法,因此set
设置ErrorLevel
to 1
. The 2> nul
部分避免了消息The syntax of the command is incorrect.
要显示。
要设置ErrorLevel
明确地你也可以使用cmd /C exit /B 1
。也许这条线更清晰。当然它更灵活,因为您可以指定任何(带符号的 32 位)数字,包括0
清除它(省略数字也会清除它)。但在性能方面可能会差一些。
应用实例
以下批处理文件演示了如何应用上述解决方法:
:DELETE
echo Deleting "%~1"...
rem this line resets ErrorLevel initially:
cmd /C exit /B
rem this line constitutes the work-around:
for /F "tokens=*" %%# in ('del /F /Q "C:\Users\newuser\Desktop\%~1" 2^>^&1 1^> nul') do (2> nul set =)
rem this is the corrected ErrorLevel query:
if not ErrorLevel 1 echo Deleted "%~1" succesfully.
goto :EOF
预设ErrorLevel
除了上面提到的命令之外cmd /C exit /B
,您还可以使用> nul ver
重置ErrorLevel
。这可以与for /F
像这样循环解决方法:
> nul ver & for /F "tokens=*" %%# in ('del /F /Q "\path\to\the\file_s.txt" 2^>^&1 1^> nul') do (2> nul set =)
替代方法没有for /F
而不是使用for /F
捕捉STDERR
的输出del
, the find
命令也可以像这样使用find /V ""
,它返回一个ErrorLevel
of 1
如果输入一个空字符串并且0
否则:
del "\path\to\the\file_s.ext" 2>&1 1> nul | find /V "" 1> nul 2>&1
但是,这将返回一个ErrorLevel
of 1
如果删除成功并且0
如果不。为了扭转这种行为,if
/else
子句可以像这样附加:
del "\path\to\the\file_s.ext" 2>&1 1> nul | find /V "" 1> nul 2>&1 & if ErrorLevel 1 (1> nul ver) else (2> nul set =)
不同的方法:检查文件是否存在del
一种完全不同的方法是在尝试删除文件后检查文件是否存在(感谢用户Sasha https://stackoverflow.com/users/1421194为了hint https://stackoverflow.com/questions/22953027/batch-file-and-del-errorlevel-0-issue/33403497#comment100505753_33403497!),像这样,例如:
del /F /Q "\path\to\the\file_s.txt" 1> nul 2>&1
if exist "\path\to\the\file_s.txt" (2> nul set =) else (1> nul ver)