批处理必须从特定位置删除文件和目录,并将成功或stdout / stderr消息输出到新的.txt文件。我已经创建了大部分脚本,它完全按照预期执行,除非删除成功,它会向前移动到下一行,而不是回应成功的#39;日志上的消息。
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 success echo成功的语法'。在上面的示例中,如果我删除行
if errorlevel 0 echo successful
一切正常,但没有成功的消息。留下这条线就可以说明每一条线的成功。
答案 0 :(得分:7)
del
和ErrorLevel
?只要给定的参数有效,del
命令就不会设置ErrorLevel
,在这种情况下它甚至会将ErrorLevel
重置为0
(至少对于del
Windows 7)。
ErrorLevel
仅在提供无效切换的情况下修改del /X
(ErrorLevel
将1
设置为del
),根本不指定任何参数( ErrorLevel
也将1
设置为del :
,或者提供了错误的文件路径(ErrorLevel
将123
设置为STDERR
),至少Windows 7。
可能的解决方法是捕获del
的{{1}}输出,因为如果删除错误,相关消息(Could Not Find [...]
,Access is denied.
,{{ 1}})写在那里。这可能看起来像:
The process cannot access the file because it is being used by another process.
要直接在命令提示符中使用代码而不是在批处理文件中,请编写for /F "tokens=*" %%# in ('del /F /Q "\path\to\the\file_s.txt" 2^>^&1 1^> nul') do (2> nul set =)
而不是%#
。
如果您不想删除只读文件,请从%%#
命令行中删除/F
;
如果您确实需要提示(如果文件路径中存在通配符del
和/或?
),请删除*
。
执行命令行/Q
。在del /F /Q "\path\to\the\file_s.txt"
部分,2>&1 1> nul
处的命令输出将被取消,其STDOUT
输出将被重定向,以便STDERR
接收它。
如果删除成功,for /F
不会生成del
输出,因此STDERR
循环不会迭代,因为没有要解析的内容。请注意,for /F
在这种情况下不会被重置,其值保持不变。
如果ErrorLevel
收到for /F
命令行的任何STDERR
输出,则执行循环体中的命令,即del
;这是一种无效的语法,因此set =
将set
设置为ErrorLevel
。 1
部分避免显示消息2> nul
。
要明确设置The syntax of the command is incorrect.
,您还可以使用ErrorLevel
。也许这条线更清晰。确保它更灵活,因为您可以声明任何(带符号的32位)数字,包括cmd /C exit /B 1
以清除它(省略数字也会清除它)。但是在性能方面可能会有点差。
以下批处理文件演示了如何应用上述解决方法:
0
: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\newuser\Desktop\%~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
> nul ver & for /F "tokens=*" %%# in ('del /F /Q "\path\to\the\file_s.txt" 2^>^&1 1^> nul') do (2> nul set =)
而不是使用for /F
来捕获for /F
的{{1}}输出,STDERR
命令也可以像del
一样使用,它返回find
1}} find /V ""
如果有空字符串,则为ErrorLevel
:
1
但是,如果删除成功,这将返回1
del "\path\to\the\file_s.ext" 2>&1 1> nul | find /V "" 1> nul 2>&1
,如果没有,则返回ErrorLevel
。要扭转这种行为,可以像这样附加1
/ 0
子句:
if
答案 1 :(得分:1)
使用此语法时,而不是此
if errorlevel 0 echo successful
你可以使用它 - 因为errorlevel 0总是为真。
if not errorlevel 1 echo successful
答案 2 :(得分:1)
答案 3 :(得分:0)
到目前为止,我记得正确的语法是:
if %errorlevel% == 0 echo succesful
百分号是检查环境变量的暗示。
答案 4 :(得分:0)
这是作为原始提问者的编辑添加的,我已将其转换为社区维基答案,因为它应该是答案,而不是编辑。
我发现了怎么做......无论如何都是这样。
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
答案 5 :(得分:0)
如果ERRORLEVEL 0 [cmd]每次都会执行,因为IF ERRORLEVEL#检查ERRORLEVEL的值是否大于或等于#。因此,每个错误代码都会导致执行[cmd]。
一个很好的参考是:http://www.robvanderwoude.com/errorlevel.php
>IF /?
Performs conditional processing in batch programs.
IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command
NOT Specifies that Windows should carry out
the command only if the condition is false.
ERRORLEVEL number Specifies a true condition if the last program run
returned an exit code equal to or greater than the number
specified.
我建议您将代码修改为以下内容:
: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
OR
:delete
echo deleting %1
del /f /q c:\Users\newuser\Desktop\%1
goto :delete_error%ERRORLEVEL% || goto :delete_errorOTHER
:delete_errorOTHER
echo Unknown error: %ERRORLEVEL%
GOTO :delete_errorcheck_done
:delete_error3
echo Cannot find path
GOTO :delete_errorcheck_done
:delete_error2
echo Cannot find file
GOTO :delete_errorcheck_done
:delete_error0
echo succesful
:delete_errorcheck_done
GOTO :EOF
答案 6 :(得分:0)
aschipfl 的答案很棒(非常感谢,帮了我很多忙!)使用 Presetting ErrorLevel 下的代码,你得到了一个很好的标准函数:
请注意在AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
语句中使用%~1
代替%1
,否则如果使用带引号的文件名,则会出错。
del
BTW 1:你可以给出一个漂亮的错误信息作为第二个参数
顺便说一句2:使用::######################################################################
::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
代替::
进行评论会使代码更具可读性。
答案 7 :(得分:0)
错误代码: (您所做的事情)
if errorlevel 0 echo succesful
这里的问题是您没有将错误级别作为变量调用,而且您也没有将运算符添加到语句中。
正确的代码: (此处应为实际内容。)
if %ERRORLEVEL% EQU 0 echo succesful
EQU: EQU代表Equal。这种运算符也称为关系运算符。如果您想了解更多信息,请点击documentation链接到运营商,还有其他链接,但这对我有所帮助。
ERRORLEVEL:被声明为变量,通常会获取上一次运行命令的错误级别。变量通常在这样的百分号之间时被调用
%foo%
有关变量的更多帮助,请转到cmd(您可以在Windows 10上通过搜索找到该变量),然后键入“ set /?”(不带引号)。 set命令是用于设置变量的命令