【问题标题】:Returning errorlevels with xcopy from multiple directories使用 xcopy 从多个目录返回错误级别
【发布时间】:2017-02-15 20:08:44
【问题描述】:

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

这是目录结构图。

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

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

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

第三次编辑:我创建了一个测试场景。我在桌面上创建了 2 个文件夹,分别命名为“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 . . . 

【问题讨论】:

  • if errorlevel 1 更改为if not errorlevel 2if errorlevel n 对等于或大于 n 的任何值都为真
  • So.. 如果 errorlevel 为 1 那么对于 errorlevel 为 0 也是如此?
  • 是的。如果 errorlevel 为 5,则任何等于或低于 5 的值的检查都将为真。当您使用if errorlevel 语法进行测试时,您会检查从高到低的值。
  • @MCND 见我上面的编辑。

标签: batch-file error-handling xcopy errorlevel


【解决方案1】:

已编辑最后的原始回复。

我应该遗漏一些明显的东西,但是,我一直无法让 xcopy.exe(Windows 10 64 位,西班牙语区域设置)生成 errorlevel 1 退出代码,无论是否记录在案。

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

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

  • 没有一个exit调用使用1的值

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

  • 1234563 (File not found - %1),调用中使用的退出码为4

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

注意:对于任何读者,如果您知道我没有看到什么,请发表评论。

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

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
    )
)

【讨论】:

  • 当我确定没有要复制的文件时,我看到:0 个文件已复制成功 0 个文件已成功复制
  • @MCNC 我添加了另一个编辑,试图调试我的问题。
  • 我可以用什么方法:>nul 2>nul dir /a-d /s "folderName\*" && (echo Files exist) || (echo No files found) 只检查“ToBeMoved”子目录中的文件?
  • @Neal,答案已更新,但你不会喜欢它(至少,我不喜欢它)
  • @Neal,是的,我正在写作,但没有看到您的评论。
猜你喜欢
  • 2010-10-09
  • 1970-01-01
  • 2019-03-30
  • 2012-06-27
  • 2011-09-24
  • 1970-01-01
  • 2014-07-14
  • 2011-11-04
  • 1970-01-01
相关资源
最近更新 更多