当删除失败时,“rd”退出并将errorlevel设置为0,等等

时间:2012-06-21 12:01:57

标签: windows batch-file error-handling cmd exit-code

我正在编写批处理(.bat)脚本,我需要处理删除文件夹失败的情况。我正在使用%errorlevel%来捕获退出代码,但是在rd命令的情况下它似乎不起作用:

C:\Users\edo\Desktop>rd testdir
Directory is not empty

C:\Users\edo\Desktop>echo %errorlevel%
0

为什么呢?你有什么建议?

2 个答案:

答案 0 :(得分:22)

哇,这是我见过第二个没有正确设置ERRORLEVEL的案例!请参阅File redirection in Windows and %errorlevel%

解决方案与检测重定向失败的解决方案相同。使用||运算符在失败时采取措施。

rd testdir || echo The command failed!

奇怪的是,当您使用||运算符时,如果文件夹不为空,则ERRORLEVEL会正确设置为145,如果文件夹不存在,则设置为2。所以你甚至不需要做任何事情。您可以有条件地“执行”一个备注,然后将正确设置errorlevel。

rd testdir || rem
echo %errorlevel%

我认为上面给出了完整的图片。但随后的一系列评论表明,使用/RD /S时仍存在潜在问题。 如果父文件夹下的文件或子文件夹被锁定(在父级下的任何级别),则RD /S /Q PARENT && echo removed || echo failed将打印出错误消息,但&&分支将触发而不是||分支。非常不幸。如果命令因父文件夹本身被锁定而失败,则||将正确触发并设置ERRORLEVEL。

通过使用stdout交换stderr并将结果传递给FINDSTR "^",可以检测所有情况下的故障。如果找到匹配项,则必定存在错误。

3>&2 2>&1 1>&3 rd /s test | findstr "^" && echo FAILED

/q丢失时,stderr和stdout的交换很重要,因为它允许“你确定(是/否)?”提示在stderr上可见,与stdout上的错误消息分开。

答案 1 :(得分:7)

rd未将errorlevel设置为零 - 它使errorlevel保持不变:f.e。如果之前的操作以正errorlevel结束且rd成功完成,则errorlevel保持不变。示例:robocopy低于4的错误级别是警告而不是错误,可以忽略,因此即使成功删除目录,以下代码也可能以错误结束:

robocopy ...
if errorlevel 4 goto :error
rd somedir
if errorlevel 1 goto :error

解决方案:忽略错误并检查rd之后目录是否仍然存在:

rd somedir
if exist somedir goto :error