我正在编写批处理(.bat)脚本,我需要处理删除文件夹失败的情况。我正在使用%errorlevel%
来捕获退出代码,但是在rd
命令的情况下它似乎不起作用:
C:\Users\edo\Desktop>rd testdir
Directory is not empty
C:\Users\edo\Desktop>echo %errorlevel%
0
为什么呢?你有什么建议?
答案 0 :(得分:22)
解决方案与检测重定向失败的解决方案相同。使用||
运算符在失败时采取措施。
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