使用xcopy从多个目录返回错误级别

时间:2017-02-15 20:08:44

标签: batch-file error-handling xcopy errorlevel

我正在处理一个批处理脚本,该脚本将从VM上的用户目录移动文件,并生成已移动文件的日志文件。

这是目录结构的图形。

structure

此脚本从相应的目录中复制文件并生成日志文件:

set hh=%time:~-11,2%
set /a hh=%hh%+100
set hh=%hh:~1%
set dateseed=%date:~10,4%_%date:~4,2%_%date:~7,2%_%hh%%time:~3,2%
set output="C:\Users\Public\Documents\Scanned_%dateseed%.txt"
echo(

>>"%output%" (
    echo(Scanned By: %username%
    echo(Date Scanned: %mydate%
    echo(Time Scanned: %mytime%
    echo(
)

:: echoes the Username, File Name, Size(in KB), Last Modified date, and total number of files in the log file
setlocal EnableDelayedExpansion 
set "current="
set/a counter=0

>>"%output%" (
  for /f "delims=" %%F in (
    'dir /b /s \\SERVER\Path\Users ^| findstr ToBeMoved\'
  ) do (
    for /f "delims=\; tokens=3,4,5*" %%a in ("%%F") do (
      if "!current!" neq "%%b" (
         set "current=%%b"
         if defined footer echo(Total Files Moved: !counter! & echo(
         set/a counter=0, footer=1
         echo(
         echo(%%b
      )
      set/a counter+=1, size=%%~zF, kbSize=size/1024
      echo %%d -- Size: !kbSize! KB -- Last Modified: %%~tF
    )
  )
  if defined footer echo(Total Files Moved: !counter! & echo(
) 
EndLocal

dir /b /s /a:d "\\SERVER\Path\Users\*ToBeMoved" | for /f "delims=\; tokens=3,4,5*" %%a in ('findstr ToBeMoved') do @xcopy /i /s /y "\\SERVER\Path\%%a\%%b\%%c" "E:\Path\%%b\"

好的,这是我的问题。

当任何用户的“ToBeMoved”目录中没有文件时,我经常运行此脚本。这导致一个空的,无用的日志文件,使我保留的目录变得混乱。我知道xcopy在尝试从目录复制但没有找到任何文件时有错误级别。

Exit
code  Description
====  ===========
  0   Files were copied without error.
  1   No files were found to copy.
  2   The user pressed CTRL+C to terminate xcopy.
  4   Initialization error occurred. There is not
      enough memory or disk space, or you entered
      an invalid drive name or invalid syntax on
      the command line.
  5   Disk write error occurred.

所以我希望我可以在我的脚本中使用if语句来执行以下操作:if errorlevel 1 (del %output%)

但是我在脚本的@xcopy行之后添加了一个段,如下所示:

if errorlevel 1 (
    echo SUCCESS!
) else (
    echo FAILURE!
)

它始终返回FALURE!。我正在尝试做什么?

编辑:也许值得注意的是,从多个“ToBeMoved”目录复制文件的行的输出会为每个目录返回一行,所以如果没有文件,那么我会看到类似的东西:

0 File(s) copied
0 File(s) copied
0 File(s) copied
0 File(s) copied
0 File(s) copied

第二次编辑:由于评论中的建议,我将上面的if / else语句更改为if not errorlevel 2。然而,结果总是“成功!”无论是否复制文件。知道为什么会这样吗?无论如何我可以编写一个for循环来计算整个目录树中的文件数量并将其保存到一个变量中以进行检查吗?

第三次编辑:我创建了一个测试场景。我在桌面上创建了两个名为“TEST1”和“TEST2”的文件夹。里面都有3个文件夹,“SUB1”,“SUB2”和“SUB3”。在TEST1 \ SUB1中,我创建了一个名为File1.txt的空文本文件。在TEST2 \ SUB3中,我创建了另一个名为File2.txt的空文本文件。我写了一个测试批处理脚本:

@echo off
xcopy /s/i/y %userprofile%\Desktop\TEST1\SUB1 %userprofile%\Desktop\TEST2\SUB3
echo Error Level = %errorlevel%
xcopy /s/i/y %userprofile%\Desktop\TEST1\SUB2 %userprofile%\Desktop\TEST2\SUB2
echo Error Level = %errorlevel%
xcopy /s/i/y %userprofile%\Desktop\TEST1\SUB3 %userprofile%\Desktop\TEST2\SUB1
echo Error Level = %errorlevel%
xcopy /s/i/y %userprofile%\Desktop\TEST2\SUB1 %userprofile%\Desktop\TEST1\SUB3
echo Error Level = %errorlevel%
xcopy /s/i/y %userprofile%\Desktop\TEST2\SUB2 %userprofile%\Desktop\TEST1\SUB2
echo Error Level = %errorlevel%
xcopy /s/i/y %userprofile%\Desktop\TEST2\SUB3 %userprofile%\Desktop\TEST1\SUB1
echo Error Level = %errorlevel%
pause

结果是:

C:\Users\username\Desktop\TEST1\SUB1\File1.txt
C:\Users\username\Desktop\TEST1\SUB1\File2.txt
2 File(s) copied
Error Level = 0
0 File(s) copied
Error Level = 0
0 File(s) copied
Error Level = 0
0 File(s) copied
Error Level = 0
0 File(s) copied
Error Level = 0
C:\Users\username\Desktop\TEST2\SUB3\File1.txt
C:\Users\username\Desktop\TEST2\SUB3\File2.txt
2 File(s) copied
Error Level = 0
Press any key to continue . . . 

1 个答案:

答案 0 :(得分:1)

已修改最后的原始回复。

我应该遗漏一些显而易见的东西,但是,我已经无法获得xcopy.exe(Windows 10 64位,西班牙语语言环境)来生成errorlevel 1退出代码,无论是否记录。

所以,我已经启动了调试器,经过一些测试,这就是我所看到的:

  • xcopy在内部使用名为DisplayMessageAndExit的方法来显示消息并退出。它还使用了几个exit调用来使程序退出某些事件(例如 Ctrl-C

  • exit个调用均未使用值1

  • 从对DisplayMessageAndExit的调用列表中,没有人使用值1作为退出代码

  • 从对DisplayMessageAndExit的调用列表中,只有其中一个使用MessageID 0x5622(在我的安装中,关联的资源位于C:\Windows\System32\es-ES\ulib.dll.mui,它依赖于区域设置) ,即No se encuentra el archivo: %1File not found - %1),并且调用中使用的退出代码为4

也许xcopy有一种方法可以生成1退出代码,但我不知道如何。所以,我没有看到一种方法来处理使用xcopy退出代码复制的非文件的情况(这使得原始答案在这种情况下无法使用)。

note :对于任何读者,如果您知道我没有看到的内容,请发表评论。

处理它的最简单方法是首先检查是否有任何要复制的内容。 /L命令的xcopy开关将列出文件而不复制它们

for /f "tokens=3,4,* delims=\;" %%a in ('
    dir /b /s /ad "\\SERVER\Path\Users\*ToBeMoved"
') do (

    xcopy /i /s /y /l "\\SERVER\Path\%%a\%%b\%%c" "E:\Path\%%b\" | findstr /b /l /c:"0 File(s) copied" > nul
    if not errorlevel 1 (
        echo No files found
    ) else (
        xcopy /i /s /y "\\SERVER\Path\%%a\%%b\%%c" "E:\Path\%%b\" 
        if errorlevel 2 (
            echo Problems in the copy
        ) else (
            echo SUCESS
        )
    )

)

原始答案

for /f "tokens=3,4,* delims=\;" %%a in ('
    dir /b /s /ad "\\SERVER\Path\Users\*ToBeMoved"
') do (
    xcopy /i /s /y "\\SERVER\Path\%%a\%%b\%%c" "E:\Path\%%b\" 
    if errorlevel 2 (
        echo Problems in the copy
    ) else if errorlevel 1 (
        echo No files found
    ) else (
        echo SUCESS
    )
)