Batch file 批处理文件和DEL errorlevel 0问题

Batch file 批处理文件和DEL errorlevel 0问题,batch-file,cmd,echo,delete-file,errorlevel,Batch File,Cmd,Echo,Delete File,Errorlevel,批处理必须从特定位置删除文件和目录,并将success或stdout/stderr消息输出到新的.txt文件。我已经创建了大部分脚本,它的性能完全符合要求,除非删除成功,否则它会向前移动到下一行,而不是在日志上回显“成功”消息 echo Basic Deletion Batch Script > results.txt @echo off call :filelog >> results.txt 2>&1 notepad results.txt exit /b

批处理必须从特定位置删除文件和目录,并将success或stdout/stderr消息输出到新的.txt文件。我已经创建了大部分脚本,它的性能完全符合要求,除非删除成功,否则它会向前移动到下一行,而不是在日志上回显“成功”消息

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\newuser\Desktop\%1 
if errorlevel 0 echo succesful

GOTO :EOF

:remove
echo deleting directory %1
rmdir /q /s %1

GOTO :EOF
由于某些原因,我找不到if del successful的语法。在上面的示例中,如果我删除该行

if errorlevel 0 echo successful

一切正常,但没有成功的信息。留下这一行,每一行都呼应着成功

使用此语法而不是此

if errorlevel 0 echo successful
您可以使用它-因为errorlevel 0始终为真

if not errorlevel 1 echo successful
这是作为原始询问者的编辑添加的,我已将其转换为社区wiki答案,因为它应该是答案,而不是编辑

我知道怎么做了。。。反正是单程的

echo Startup > 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
dir c:\users\newuser\Desktop\%1  >NUL 2>&1
SET existed=%ERRORLEVEL%
del /f /q c:\Users\newuser\Desktop\%1 
dir c:\users\newuser\Desktop\%1 2>NUL >NUL
if %existed% == 0 (if %ERRORLEVEL% == 1  echo "successful" )

GOTO :EOF

:remove
echo deleting directory %1
rmdir /q /s %1

GOTO :EOF

IF ERRORLEVEL 0[cmd]每次都会执行,因为IF ERRORLEVEL检查ERRORLEVEL的值是否大于或等于#。因此,每个错误代码都会导致执行[cmd]

这方面的一个重要参考是:

我建议您将代码修改为以下内容:

:delete
echo deleting %1
del /f /q c:\Users\newuser\Desktop\%1 
if errorlevel 1 (
    rem This block executes if ERRORLEVEL is a non-zero
    echo failed
) else (
    echo succesful
)

GOTO :EOF
如果您需要处理多个ERRORLEVEL的程序,可以执行以下操作:

:delete
echo deleting %1
del /f /q c:\Users\newuser\Desktop\%1 
if errorlevel 3 echo Cannot find path& GOTO :delete_errorcheck_done
if errorlevel 2 echo Cannot find file& GOTO :delete_errorcheck_done
if errorlevel 1 echo Unknown error& GOTO :delete_errorcheck_done
echo succesful
:delete_errorcheck_done

GOTO :EOF

del
ErrorLevel
? 只要给定的参数有效,
del
命令就不会设置
ErrorLevel
,在这种情况下(至少对于Windows 7),它甚至会将
ErrorLevel
重置为
0

del
仅在提供无效开关(
del/X
ErrorLevel
设置为
1
)的情况下修改
ErrorLevel
),完全不指定参数(
del
也将
ErrorLevel
设置为
1
),或者提供了不正确的文件路径(
del:
ErrorLevel
设置为
123
),至少适用于Windows 7

可能的解决办法 一种可能的解决方法是捕获
del
STDERR
输出,因为在出现删除错误的情况下,相关消息(
无法找到[…]
访问被拒绝。
进程无法访问该文件,因为它正被另一个进程使用。
)都写在那里。这些可能看起来像:

for/F“tokens=*”%%#in('del/F/Q“\path\to\the\file_.txt“2^>^&11^>nul”)do(2>nul set=)
要直接在命令提示符中而不是在批处理文件中使用代码,请编写
%
而不是
%

如果不想删除只读文件,请从
del
命令行中删除
/F

如果确实需要提示(如果文件路径中存在通配符
和/或
*
),请删除
/Q

代码解释 这将执行命令行
del/F/Q“\path\to\the\file_.txt”
。通过部件
2>&11>nul
,在
STDOUT
处的命令输出将被取消,其
STDERR
输出将被重定向,以便
for/F
接收它

如果删除成功,
del
不会生成
STDERR
输出,因此,
for/F
循环不会迭代,因为没有要分析的内容。请注意,在这种情况下,
ErrorLevel
不会重置,其值保持不变

如果
for/F
del
命令行接收到任何
STDERR
输出,则执行循环体中的命令,即
set=
;这是无效语法,因此
set
ErrorLevel
设置为
1
2>nul
部分避免消息
语法命令的x不正确。
将显示

要明确设置
ErrorLevel
,您也可以使用
cmd/C exit/B 1
。也许这一行更清晰。当然,它更灵活,因为您可以声明任何(有符号的32位)数字,包括
0
来清除它(省略该数字也会清除它).不过,就性能而言,可能会差一点

应用实例 以下批处理文件演示了如何应用上述变通方法:

:删除
回显删除“%~1”。。。
rem此行最初重置错误级别:
cmd/C退出/B
rem该行构成了以下工作环境:
对于('del/F/Q“C:\Users\newuser\Desktop\%~1“2^>^&11^>nul')中的/F“tokens=*”%%#do(2>nul set=)
rem这是已更正的ErrorLevel查询:
如果不是错误级别1,则成功删除“%~1”。
后藤:EOF
预设
ErrorLevel
除了上述命令
cmd/C exit/B
,您还可以使用
>nul-ver
重置
ErrorLevel
。这可以与
for/F
循环操作结合使用,如下所示:

:delete
echo deleting %1
del /f /q c:\Users\newuser\Desktop\%1 
if errorlevel 3 echo Cannot find path& GOTO :delete_errorcheck_done
if errorlevel 2 echo Cannot find file& GOTO :delete_errorcheck_done
if errorlevel 1 echo Unknown error& GOTO :delete_errorcheck_done
echo succesful
:delete_errorcheck_done

GOTO :EOF
>nul ver&for/F“标记=*”%%#in('del/F/Q“\path\to\the\file_.txt”2^>^&1 1^>nul)do(2>nul set=)
不带
的替代方法用于/F
与使用
for/F
捕获
del
STDERR
输出不同,
find
命令也可以像
find/V”“
一样使用,如果输入空字符串,则返回
1
ErrorLevel
,否则:

del”\path\to\the\file_.ext“2>&11>nul | find/V“1>nul 2>&1
但是,如果删除成功,这将返回
ErrorLevel
of
1
,如果删除不成功,则返回
0
。要扭转这种行为,可以像下面这样附加
if
/
else
子句:

:delete
echo deleting %1
del /f /q c:\Users\newuser\Desktop\%1 
if errorlevel 3 echo Cannot find path& GOTO :delete_errorcheck_done
if errorlevel 2 echo Cannot find file& GOTO :delete_errorcheck_done
if errorlevel 1 echo Unknown error& GOTO :delete_errorcheck_done
echo succesful
:delete_errorcheck_done

GOTO :EOF
del”\path\to\the\file_.ext“2>&11>nul | find/V”1>nul 2>&1&if ErrorLevel 1(1>nul ver)else(2>nul set=)
不同的方法:在::###################################################################### ::call :DELETE "file.txt" ::call :DELETE "file.txt" "error message" :DELETE >nul ver && for /F "tokens=*" %%# in ('del /F /Q "%~1" 2^>^&1 1^> nul') do (2>nul set =) || ( if NOT .%2==. echo %~2 ) goto :EOF
if errorlevel 0 echo succesful
if %ERRORLEVEL% EQU 0 echo succesful
%foo%