Batch file 在Windows批处理文件中设置errorlevel

Batch file 在Windows批处理文件中设置errorlevel,batch-file,Batch File,我正在编写一个批处理脚本,它将循环遍历文本文件的每一行(每一行包含一个文件名),检查文件是否存在,然后运行文件并移动它 以下是我的批处理脚本: REM Loop through each line of input.txt FOR /F "tokens=1-3 delims=, " %%i IN (./ready/input.txt) DO ( ECHO. ECHO. ECHO. ECHO Check %%i exists, set error flag if it doesnt

我正在编写一个批处理脚本,它将循环遍历文本文件的每一行(每一行包含一个文件名),检查文件是否存在,然后运行文件并移动它

以下是我的批处理脚本:

REM Loop through each line of input.txt
FOR /F "tokens=1-3 delims=, " %%i IN (./ready/input.txt) DO (
  ECHO.
  ECHO.
  ECHO.
  ECHO Check %%i exists, set error flag if it doesnt
  if not exist .\ready\%%i set errorlevel=2
echo return code is %errorlevel%

  ECHO Run %%i if it exists
  if errorlevel 0 call .\ready\%%i

  ECHO Move %%i to archive if no error occured 
  if errorlevel 0 copy .\ready\%%i .\archive\%mydate%_%mytime%_%%j_%%k_%%i

  ECHO Copy line of text to the new output.txt file if an error occured
  if %errorlevel% NEQ 0 >>output.txt %%i, %%j, %%k
)
以下是输出:

我不明白为什么“if errorlevel”没有按预期工作。。。如果文件不存在(如本例中不存在的文件),则不应尝试运行该文件,也不应复制该文件,并且应回显2而不是0

编辑1:我正在阅读另一篇关于“延迟环境变量扩展”的文章,我不确定这个问题是否相关 SETLOCAL DEL output.txt 2>nul REM循环通过input.txt的每一行 对于(.\ready\input.txt)中的/F“tokens=1-3 delims=,”%%i( 回声。 回声。 回声。 回显检查%%i存在,如果不存在则设置错误标志 如果存在。\ready\%i(设置“errorflag=”)ELSE(设置errorflag=2) 呼叫回显返回代码为%%errorflag%% 回显运行%%i(如果存在) 如果未定义errorflag( 呼叫。\ready\%i 如果未发生错误,则回显将%%i移动到存档 如果errorlevel 1(设置errorflag=3)其他(回显副本。\ready\%i。\archive\%mydate%\u%mytime%\uj%%k%%i) ) 如果发生错误,将文本的复制行回显到新的output.txt文件中 如果定义了errorflag>>output.txt ECHO%%i、%%j、%%k ) 后藤:EOF 这里有一个重写的过程

注意:
output.txt
在开始时被删除,否则
>
将附加到任何现有文件中<代码>2>nul在删除失败时抑制错误消息(例如文件不存在)

在块语句
(括号内的一系列语句)
中,整个块被解析并执行。块内的任何
%var%
将在执行块之前,在解析块时被该变量的值替换

因此,在遇到
IF
时,将使用
%variables%
的值执行
IF(somethingelse)

克服此问题的两种常见方法是:1)使用
setlocal enabledelayedexpansion
!瓦尔
代替
%var%
访问
var
的更改值,或2)调用子例程使用更改的值执行进一步处理

因此,请注意使用了
CALL ECHO%%var%%
,它显示了
var
的更改值<代码>调用ECHO%%errorlevel%%显示,但遗憾的是随后重置errorlevel

如果
var
当前已定义,则
IF DEFINED var
为真

ERRORLEVEL
是一个特殊的可变名称。它由系统设置,但如果由用户设置,则用户指定的值将覆盖系统值

如果ERRORLEVEL n
为真,如果
ERRORLEVEL
为n或大于n<如果ERRORLEVEL 0因此始终为真,则代码>

语法
设置“var=value”
(其中值可能为空)用于确保指定的值中不包括行尾的任何多余空格

所需命令仅用于测试目的。验证命令是否正确后,将
ECHO COPY
更改为
COPY
,以实际复制文件

我使用了以下
input.txt

seterr1.bat, J1, K1
seterr5.bat,J2,K2
seterr0.bat,J3 K3
seterr5.bat, J4, K4
notexist.bat, J5, K5
包含以下内容的现有文件
seterr*.bat

@ECHO关闭
退出/b 1
(其中最后一行中的
1
确定返回的
errorlevel

并收到结果输出:

Check seterr1.bat exists, set error flag if it doesnt
return code is 
Run seterr1.bat if it exists
Move seterr1.bat to archive if no error occured
Copy line of text to the new output.txt file if an error occured

Check seterr5.bat exists, set error flag if it doesnt
return code is 
Run seterr5.bat if it exists
Move seterr5.bat to archive if no error occured
Copy line of text to the new output.txt file if an error occured

Check seterr0.bat exists, set error flag if it doesnt
return code is 
Run seterr0.bat if it exists
Move seterr0.bat to archive if no error occured
copy .\ready\seterr0.bat .\archive\__J3_K3_seterr0.bat
Copy line of text to the new output.txt file if an error occured

Check seterr5.bat exists, set error flag if it doesnt
return code is 
Run seterr5.bat if it exists
Move seterr5.bat to archive if no error occured
Copy line of text to the new output.txt file if an error occured

Check notexist.bat exists, set error flag if it doesnt
return code is 2
Run notexist.bat if it exists
Copy line of text to the new output.txt file if an error occured
请注意,正如我前面提到的那样,副本只是
ECHO
ed

和output.txt

seterr1.bat, J1, K1
seterr5.bat, J2, K2
seterr5.bat, J4, K4
notexist.bat, J5, K5

仅当%%i项目存在时,才可执行该项目,并检查错误、移动或记录。如果%%i项目不存在,则它将不起任何作用

REM Loop through each line of input.txt
FOR /F "tokens=1-3 delims=, " %%i IN (.\ready\input.txt) DO (
  ECHO.
  ECHO.
  ECHO.
  ECHO Check %%i exists, execute it if it does
  if exist .\ready\%%i (
    call .\ready\%%i
    ECHO Move %%i to archive if no error occured 
    if not errorlevel 1 (
        copy .\ready\%%i .\archive\%mydate%_%mytime%_%%j_%%k_%%i
      ) else (
        ECHO Copy line of text to the new output.txt file if an error occurred
        >>output.txt %%i, %%j, %%k
      )
  )
)

ERRORLEVEL
%ERRORLEVEL%
是两个不同的变量。这意味着您的回波返回代码为%errorlevel%,如果%errorlevel%NEQ 0>>output.txt%%i、%%j、%%k可能是错误的,则返回代码为%errorlevel%

ERRORLEVEL
内置,用于获取最后一个命令的结果。您可以像这样使用它:

IF ERRORLEVEL 1 ECHO error level is 1 or more
ERRORLEVEL
无法设置,就像bash不允许您设置?=…

%ERRORLEVEL%
是一个环境变量。如果设置了
%ERRORLEVEL%
,则在使用
%ERRORLEVEL%
时在脚本中使用它。如果未设置
%ERRORLEVEL%
,如果启用了命令扩展,则返回到
ERRORLEVEL
<代码>错误级别不更新
%ERRORLEVEL%


Raymond Chen有一篇很好的博客:。这个答案中的一些内容被无耻地从中删除。

使用类似以下子程序的内容:

:return
   ECHO @exit /b %1 >ret.cmd
   CALL ret.cmd
   GOTO :eof
然后像这样使用它:

:Attempt
   SETLOCAL
   CALL somethingThatFails
   SET retcode=!errorlevel!
   CALL somethingThatPasses : don't care about the errorlevel here
   CALL :return !retcode!
   ENDLOCAL
   CALL :eof
所以,整个事情看起来就像:

test.cmd

@ECHO OFF

SETLOCAL ENABLEDELAYEDEXPANSION

CALL :Attempt
IF !errorlevel! NEQ 0 (ECHO Attempt Failed) ELSE (ECHO Attempt succeeded!)
GOTO :eof

:Attempt
   SETLOCAL
   CALL somethingThatFails
   SET retcode=!errorlevel!
   CALL somethingThatPasses : don't care about the errorlevel here
   CALL :return %retcode%
   ENDLOCAL
   CALL :eof

:return
   ECHO @exit /b %1 >return.cmd
   CALL ret.bat
   GOTO :eof
有些东西失败了。cmd

DIR some command that fails >nul 2>&1
有些东西通过了。cmd

DIR >nul 2>&1

这样做的一个副作用是一个名为ret.cmd的文件。我通常使用一个:end子例程进行清理并将其删除。

如果您执行
如果不执行“%errorlevel%”==“0”
,会发生什么情况?另外,可能不设置
errorlevel
本身:@zero298使用%errorlevel%时会发生同样的情况-无法查看该博客,因为我的工作正在阻止它=(还尝试删除设置的errorlevel没有引起任何更改另一件事我,为什么你有
\file\other
为什么不只是
file/other
@zero298我刚刚习惯使用。\n要转到文件夹路径中的相对子文件夹-个人首选项
设置errorlevel=2
之间有什么区别:if exist output.txt(ECHO Y | DEL output.txt)和DEL output.txt 2>nul?实际上,不是。第二个更容易键入。@Kairan