首页 文章

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

提问于
浏览
1

在这个批处理脚本中,我正在测试期望 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

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

    @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 表示命令/应用程序的退出代码是 greater or equal 2 ,因此 if errorlevel 5 必须是第一个IF条件 .

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

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

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

    但最好是使用 if not errorlevel 1 ,这意味着前一个命令/应用程序的退出代码是 lower than 1 . 几乎所有应用程序在成功时退出 0 ,在错误条件下退出正数 0 . 因此,在命令块内工作的 if not errorlevel 1 几乎总是比 if %ERRORLEVEL% == 0 好,以便成功进行测试 .

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

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

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

    • del /?

    • echo /?

    • for /?

    • goto /?

    • move /?

    • net /?

    • net use /?

    • pause /?

    • rem /?

    • set /?

    • xcopy /?

    也可以看看:

相关问题