Search code examples
windowsbatch-filexcopy

xcopy - copy at least one file matching a pattern


Whenever xcopy fails to find a file, it changes the errorLevel variable from 0 to something else. In our company we have large scripts that copy files using xcopy and take actions based on this errorLevel.

It works absolutely fine for specific files or directories.

Works absolutely fine:

xcopy file dir
if %errorlevel% neq 0 exit -1

However, if, instead of specifying the exact name of a file I want to use a *, then checking errorLevel would no longer work.

Doesn't work:

xcopy file* dir
if %errorlevel% neq 0 exit -1

I'll get:

File not found - file*

0 File(s) copied

But errorLevel would be 0.

How can I make sure that at least 1 file is copied when using the wildcard?


Solution

  • The xcopy command, when using wildcards, does not consider zero matching files as an error.

    As a work-around, you can use the where command to check if there is at least one matching item, in which case it sets the ErrorLevel to 0, but to 1 otherwise. Adding the switch /Q prevents where from outputting anything and lets it just return the ErrorLevel:

    where /Q "file*"
    if %errorlevel% neq 0 exit -1
    xcopy "file*" "dir"
    if %errorlevel% neq 0 exit -1
    

    You cannot do a single check of ErrorLevel, because xcopy will overwrite the ErrorLevel of where. However, you can shorten the above like this:

    where /Q "file*" || exit -1
    xcopy "file*" "dir" || exit -1
    

    Or even like this:

    where /Q "file*" && xcopy "file*" "dir" || exit -1
    

    I have put all file and directory specifications in between quotation marks here, because this is the only secure way in case any of them contain white-spaces.