[英]"rd" exits with errorlevel set to 0 on error when deletion fails, etc
I'm writing a batch (.bat) script and I need to handle the case in which the deletion of a folder fails.我正在编写一个批处理 (.bat) 脚本,我需要处理文件夹删除失败的情况。 I'm using %errorlevel%
to catch the exit code, but in the case of the rd
command it seems not to work:我正在使用%errorlevel%
来捕获退出代码,但在rd
命令的情况下,它似乎不起作用:
C:\Users\edo\Desktop>rd testdir
Directory is not empty
C:\Users\edo\Desktop>echo %errorlevel%
0
Why?为什么? What do you suggest?你有什么建议?
Wow, this is the 2nd case I've seen where ERRORLEVEL is not set properly!哇,这是我见过的 ERRORLEVEL 设置不正确的第二个案例! See File redirection in Windows and %errorlevel% .请参阅Windows 中的文件重定向和 %errorlevel% 。
The solution is the same as for detecting redirection failure.解决方案与检测重定向失败相同。 Use the ||
使用||
operator to take action upon failure.操作员在失败时采取措施。
rd testdir || echo The command failed!
The bizarre thing is, when you use the ||
奇怪的是,当你使用||
operator, the ERRORLEVEL is then set properly to 145 if the folder was not empty, or 2 if the folder did not exist.如果文件夹不为空,则 ERRORLEVEL 将正确设置为 145,如果文件夹不存在,则设置为 2。 So you don't even need to do anything.所以你甚至不需要做任何事情。 You could conditionally "execute" a remark, and the errorlevel will then be set properly.您可以有条件地“执行”注释,然后将正确设置错误级别。
rd testdir || rem
echo %errorlevel%
I thought the above gave a complete picture.我认为上面给出了一个完整的图片。 But then a series of comments below demonstrated there are still potential problems when /RD /S
is used.但是下面的一系列评论表明,在使用/RD /S
时仍然存在潜在问题。 If a file or subfolder under the parent folder is locked (at any level under parent) then RD /S /Q PARENT && echo removed || echo failed
如果父文件夹下的文件或子文件夹被锁定(在父文件夹下的任何级别),则RD /S /Q PARENT && echo removed || echo failed
RD /S /Q PARENT && echo removed || echo failed
will print out an error message, but the &&
branch fires instead of the ||
RD /S /Q PARENT && echo removed || echo failed
将打印出一条错误消息,但是&&
分支而不是||
会触发branch.分支。 Very unfortunate.很不幸。 If the command fails because the parent folder itself is locked, then ||
如果命令因为父文件夹本身被锁定而失败,则||
will properly fire and set the ERRORLEVEL.将正确触发并设置 ERRORLEVEL。
It is possible to detect failure in all cases by swapping stderr with stdout and piping the result to FINDSTR "^"
.通过将 stderr 与 stdout 交换并将结果传送到FINDSTR "^"
可以在所有情况下检测失败。 If a match is found, then there must have been an error.如果找到匹配项,则一定存在错误。
3>&2 2>&1 1>&3 rd /s test | findstr "^" && echo FAILED
The swap of stderr and stdout is important when /q
is missing because it allows the "Are you sure (Y/N)?"当/q
丢失时,stderr 和 stdout 的交换很重要,因为它允许“你确定(是/否)吗?” prompt to be visible on stderr, separate from the error message on stdout.提示在 stderr 上可见,与 stdout 上的错误消息分开。
rd
does not set errorlevel
to zero - it leaves errorlevel
intact: fe if previous operation ends in positive errorlevel
and rd
finishes successfully it leaves errorlevel
unchanged. rd
不会将errorlevel
设置为零 - 它使errorlevel
保持不变:fe 如果之前的操作以正errorlevel
结束并且rd
成功完成,则它使errorlevel
保持不变。 Example: error levels of robocopy
below 4 are warnings and not errors and can be ignored so the following code may end with error even when the directory was deleted successfully:示例:低于 4 的robocopy
错误级别是警告而不是错误,可以忽略,因此即使目录已成功删除,以下代码也可能以错误结尾:
robocopy ...
if errorlevel 4 goto :error
rd somedir
if errorlevel 1 goto :error
Solution: ignore the error and check if the directory still exists after rd
:解决方法:忽略该错误并检查rd
后目录是否仍然存在:
rd somedir
if exist somedir goto :error
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.