xcopy错误级别返回零而不是1没有找到文件来复制

时间:2018-04-09 17:17:54

标签: batch-file errorlevel

在这个批处理脚本中,我测试了预期1的错误级别返回,但它回显了0

如果没有要复制的文件,文件夹为空,为什么它会成功返回0

我按照以下xcopy错误级别进行操作:

  

XCOPY应返回以下退出代码:

     
      
  • 0文件被复制且没有错误。
  •   
  • 1未找到任何文件要复制。
  •   
  • 2用户按下CTRL + C终止xcopy。
  •   
  • 4发生初始化错误。内存或磁盘空间不足,或者在命令行中输入了无效的驱动器名称或无效语法。
  •   
  • 5发生磁盘写入错误。
  •   

这是我的批处理脚本:

@ECHO ON
SET ERRORS=0

REM Backup file first and report any errors if unsuccessful
xcopy /Y "C:\channels\filetransfer_process\*" "C:\channels\backup\"
echo %ERRORLEVEL%
REM Error Checking
REM Note The environmental variable ERRORLEVEL contains the return code of 
the last executed program or script.
if errorlevel 2 (
    SET BODY="not enough memory or disk space"
    GOTO :mailerror

)
if errorlevel 1 (
    SET BODY="No files were found to copy"
    GOTO :mailerror
)

if errorlevel 5 (
    SET BODY="Disk write error occurred"
    GOTO :mailerror
)
if NOT ["%errorlevel%"]==["0"] pause

REM Before doing the network connection make sure Z drive is free for use
if exist z:\ (  net use z: /delete )


REM proceed with a network connection using Z with error checking
net use Z: \\dcqwdbs034\D$\arrivals /user:sutter-chs\lawson Sutter1
if errorlevel 0 (
   goto :move
) else (
   SET BODY="net use connection failed"
   goto :mailerror
)

REM move file to MSCM server
:move
move /Y "C:\channels\filetransfer_process\*" "Z:\"
if errorlevel 1 (
    SET BODY="File not found, could not be moved/renamed or bad parameters"
    goto :mailerror
)

REM remove network mapped Z drive
net use z: /delete

REM perform the error notification via BLAT
:mailerror
"D:\Program Files\BLAT\blat.exe" -Install -Server mail1.sutterhealth.org -f 
 name@domain.org -u name@domain.org -Pw mypasswd
"D:\Program Files\BLAT\blat.exe" -To name@domain.org.org -Subject "File 
Transfer Error" -Body %BODY%
:EOF

1 个答案:

答案 0 :(得分:0)

这是重写的批处理文件,以正确处理所有错误条件(希望未经完全测试)。

@echo off
REM Backup files first and report any errors if not successful
%SystemRoot%\System32\xcopy.exe "C:\channels\filetransfer_process\*" "C:\channels\backup\" /C /Q /Y >"%TEMP%\%~n0.tmp"

REM Error checking
REM Note: The environment variable ERRORLEVEL contains the
REM       return code of  the last executed program or script.
if errorlevel 5 SET "BODY=File write error occurred" & GOTO MailError
if errorlevel 2 SET "BODY=Not enough memory or free space" & GOTO MailError
if not errorlevel 1 pause

set "FileCount=0"
for /F "usebackq" %%I in ("%TEMP%\%~n0.tmp") do set "FileCount=%%I"
if "FileCount" == "0" SET "BODY=No files were found to copy" & GOTO MailError

REM Temporary file with number of copied files as last line no longer needed.
del "%TEMP%\%~n0.tmp"
set "FileCount="

REM Before doing the network connection make sure Z drive is free for use
%SystemRoot%\System32\net.exe use Z: /delete 2>nul

REM Proceed with a network connection using Z with error checking.
%SystemRoot%\System32\net.exe use Z: \\dcqwdbs034\D$\arrivals password /user:domain\username /persistent:no
if errorlevel 1 SET "BODY=Net use connection failed" & GOTO MailError
if not exist Z:\ SET "BODY=Net use connection failed" & GOTO MailError

REM Move files to MSCM server.
move /Y "C:\channels\filetransfer_process\*" "Z:\"
if errorlevel 1 (
    %SystemRoot%\System32\net.exe use Z: /delete
    SET "BODY=File not found, could not be moved/renamed or bad parameters"
    GOTO MailError
)

REM Remove network mapped Z drive.
%SystemRoot%\System32\net.exe use Z: /delete
goto :EOF

REM Perform the error notification via BLAT.
:MailError
del "%TEMP%\%~n0.tmp" 2>nul
"D:\Program Files\BLAT\blat.exe" -Install -Server mail1.sutterhealth.org -f name@domain.org -u name@domain.org -Pw mypasswd "D:\Program Files\BLAT\blat.exe" -To name@domain.org.org -Subject "File Transfer Error" -Body "%BODY%"
使用选项/Q执行

XCOPY 以禁止复制文件的输出。但 XCOPY 仍然输出复制文件的最终摘要信息。此输出将重定向到临时文件中以供以后评估。但首先是评估 XCOPY 的退出代码。

if errorlevel 2表示命令/应用程序的退出代码大于或等于 2,因此if errorlevel 5必须是第一个IF条件。

[]对字符串比较没有特殊含义。它们只是两个字面字符。所以不要在字符串比较中添加它们。 if NOT "%errorlevel%"=="0" pause就足够了。

双引号对于命令解释器具有特殊含义,因为它标记参数字符串的开始/结束,其中字符应按字面解释,但启用延迟扩展时除%!外。但请注意,在比较两个参数时, IF 始终包含"。换句话说,if在比较参数之前不会删除周围的双引号。

ERRORLEVEL始终将整数值指定为字符串,因此使用if NOT %ERRORLEVEL% == 0 pause使字符串比较更快一些是安全的,因为只需要比较两个字节(ASCII表示{ {1}}和字符串终止空字节,即0x30,0x00)而不是四个字节(引用字节,0的ASCII表示,引用字节和字符串终止空字节,即0x22,0x30,0x22,0x00)。

但最好是使用0,这意味着前一个命令/应用程序的退出代码低于 if not errorlevel 1。几乎所有应用程序在成功时退出1,在错误情况下退出正数0。因此,0在命令块中工作几乎总是比if not errorlevel 1更好地进行成功测试。

此批处理文件中使用的带有选项if %ERRORLEVEL% == 0 FOR 命令逐行读取指定文件中的行,跳过空行,跳过以分号开头的行,将每个行分开使用默认分隔符空格和水平制表符将行划分为子字符串,并将第一个空格/制表符分隔的字符串分配给指定的循环变量/F。在这种情况下,这应该始终是复制文件的数量。

应用程序 NET 在错误时通常不会以大于0的值退出。因此,在将网络共享映射到驱动器号后,请更好地验证驱动器I是否确实存在。并且最好使网络驱动器映射不持久存储在当前用户的Windows注册表中。 BTW:有问题的代码中发布的域名,用户名和密码有望伪造数据。

要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。

  • Z:
  • del /?
  • echo /?
  • for /?
  • goto /?
  • move /?
  • net /?
  • net use /?
  • pause /?
  • rem /?
  • set /?

另见: