批处理文件和 DEL 错误级别 0 问题 [英] Batch file and DEL errorlevel 0 issue
问题描述
批处理必须从特定位置删除文件和目录,并将成功或 stdout/stderr 消息输出到新的 .txt 文件.我已经创建了脚本的大部分内容,它完全按照预期执行,除非删除成功后它会前进到下一行,而不是在日志上回显成功"消息.
The batch has to remove files and directories from specific locations and output success or stdout/stderr messages to a new .txt file. I have created the most of the script and it performs exactly as it should, except when the deletion is successful it moves forward to the next line rather than echo a 'successful' message on the log.
echo Basic Deletion Batch Script > results.txt
@echo off
call :filelog >> results.txt 2>&1
notepad results.txt
exit /b
:filelog
call :delete new.txt
call :delete newer.txt
call :delete newest.txt
call :remove c:NoSuchDirectory
GOTO :EOF
:delete
echo deleting %1
del /f /q c:Users
ewuserDesktop\%1
if errorlevel 0 echo succesful
GOTO :EOF
:remove
echo deleting directory %1
rmdir /q /s %1
GOTO :EOF
出于某种原因,我找不到 if del successes echo 'successful' 的语法.在上面的例子中,如果我删除了
For some reason I can't find the syntax for if del succeeds echo 'successful'. In the above example if I remove the line
if errorlevel 0 echo successful
一切正常,但没有成功消息.留下这条线,它对每一行都表示成功.
Everything works fine, but no success message. With this line left in it echoes success for every line.
推荐答案
del
和 ErrorLevel
?
del
命令不会设置 ErrorLevel
只要给定的参数有效,它甚至会将 ErrorLevel
重置为 0
在这种情况下(至少对于 Windows 7).
del
and ErrorLevel
?
The del
command does not set the ErrorLevel
as long as the given arguments are valid, it even resets the ErrorLevel
to 0
in such cases (at least for Windows 7).
del
仅在提供无效开关的情况下修改 ErrorLevel
(del/X
将 ErrorLevel
设置为1
),根本没有指定任何参数(del
也将 ErrorLevel
设置为 1
),或者文件不正确给出路径(del :
将 ErrorLevel
设置为 123
),至少对于 Windows 7.
del
modifies the ErrorLevel
only in case an invalid switch is provided (del /X
sets ErrorLevel
to 1
), no arguments are specified at all (del
sets ErrorLevel
to 1
too), or an incorrect file path is given (del :
sets ErrorLevel
to 123
), at least for Windows 7.
一种可能的解决方法是捕获 del
的 STDERR
输出,因为如果出现删除错误,相关消息(Could Not Find [...]
, 访问被拒绝.
, 进程无法访问该文件,因为它正被另一个进程使用.
) 写在那里.这可能看起来像:
A possible work-around is to capture the STDERR
output of del
, because in case of deletion errors, the related messages (Could Not Find [...]
, Access is denied.
, The process cannot access the file because it is being used by another process.
) are written there. Such might look like:
for /F "tokens=*" %%# in ('del /F /Q "path o hefile_s.txt" 2^>^&1 1^> nul') do (2> nul set =)
要直接在命令提示符中而不是在批处理文件中使用代码,请编写 %#
而不是 %%#
.
To use the code in command prompt directly rather than in a batch file, write %#
instead of %%#
.
如果不想删除只读文件,请从/F
;
如果您确实需要提示(如果文件路径中存在通配符 ?
和/或 *
),请删除 /Q
.
If you do not want to delete read-only files, remove /F
from the del
command line;
if you do want prompts (in case wildcards ?
and/or *
are present in the file path), remove /Q
.
这将执行命令行del/F/Qpath o hefile_s.txt"
.由部分 2>&1 1>nul
,STDOUT
处的命令输出将被解除,其 STDERR
输出将被重定向,以便 for/F
接收它.
This executes the command line del /F /Q "path o hefile_s.txt"
. By the part 2>&1 1> nul
, the command output at STDOUT
will be dismissed, and its STDERR
output will be redirected so that for /F
receives it.
如果删除成功,del
不会生成 STDERR
输出,因此 for/F
循环不会迭代,因为有没什么好解析的.注意 ErrorLevel
在这种情况下不会被重置,它的值保持不变.
If the deletion was successful, del
does not generate a STDERR
output, hence the for /F
loop does not iterate, because there is nothing to parse. Notice that ErrorLevel
will not be reset in that case, its value remains unchanged.
如果 for/F
从 del
命令行收到任何 STDERR
输出,则执行循环体中的命令,即 <代码>设置=代码>;这是无效的语法,因此 set
将 ErrorLevel
设置为 1
.<代码>2>null 部分避免了消息命令的语法不正确.
被显示.
If for /F
recieves any STDERR
output from the del
command line, the command in the loop body is executed, which is set =
; this is an invalid syntax, therefore set
sets the ErrorLevel
to 1
. The 2> nul
portion avoids the message The syntax of the command is incorrect.
to be displayed.
要明确设置ErrorLevel
,您还可以使用cmd/C exit/B 1
.也许这条线更清晰.当然它更灵活,因为您可以声明任何(有符号的 32 位)数字,包括 0
来清除它(省略数字也会清除它).不过在性能方面可能会差一些.
To set the ErrorLevel
explicitly you could also use cmd /C exit /B 1
. Perhaps this line is more legible. For sure it is more flexible because you can state any (signed 32-bit) number, including 0
to clear it (omitting the number clears it as well). It might be a bit worse in terms of performance though.
以下批处理文件演示了如何应用上述解决方法:
The following batch file demonstrates how the above described work-around could be applied:
: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
ewuserDesktop\%~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
循环解决方法相结合,如下所示:
Presetting ErrorLevel
Besides the above mentioned command cmd /C exit /B
, you can also use > nul ver
to reset the ErrorLevel
. This can be combined with the for /F
loop work-around like this:
> nul ver & for /F "tokens=*" %%# in ('del /F /Q "path o hefile_s.txt" 2^>^&1 1^> nul') do (2> nul set =)
没有for/F
的替代方法代替使用 for/F
来捕获 del
的 STDERR
输出,find
命令也可以像 find/V ""
一样使用,如果传入一个空字符串并且 0<,它会返回
ErrorLevel
的 1
/code> 否则:
Alternative Method Without for /F
Instead of using for /F
to capture the STDERR
output of del
, the find
command could also be used like find /V ""
, which returns an ErrorLevel
of 1
if an empty string comes in and 0
otherwise:
del "path o hefile_s.ext" 2>&1 1> nul | find /V "" 1> nul 2>&1
然而,如果删除成功,这将返回 ErrorLevel
的 1
,否则返回 0
.为了扭转这种行为,可以像这样附加 if
/else
子句:
However, this would return an ErrorLevel
of 1
in case the deletion has been successful and 0
if not. To reverse that behaviour, an if
/else
clause could be appended like this:
del "path o hefile_s.ext" 2>&1 1> nul | find /V "" 1> nul 2>&1 & if ErrorLevel 1 (1> nul ver) else (2> nul set =)
不同的方法:在del
之后检查文件是否存在
一种完全不同的方法是在尝试删除文件后检查文件是否存在(感谢用户 Sasha 对于提示!),像这样,例如:
Different Approach: Checking File for Existence After del
A completely different approach is to check the file for existence after having tried to delete it (thanks to user Sasha for the hint!), like this, for example:
del /F /Q "path o hefile_s.txt" 1> nul 2>&1
if exist "path o hefile_s.txt" (2> nul set =) else (1> nul ver)
这篇关于批处理文件和 DEL 错误级别 0 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!