89

My batch script xcopy is still asking F = file, D = directory confirmation even though I have added /F in the script, the log is showing as below. Please help on how to avoid asking confirmation.

Script:

net use p: /delete  
net use p: "\\200clan\F_Drive" /USER:adm /PERSISTENT:NO-1111
set source=%1
set target=p:/%2

echo %source% %target%

xcopy /S /I /Q /Y /F "%source%" "%target%"

Log:

C:\test\foldera>xcopy /S /I /Q /Y /F "C:/test/folder1/folder2/logs/154/compareReport_177.html" "p:/Services/WSDLCompare/177_20151116/compareReport_177.html"
Does P:\Services\WSDLCompare\177_20151116\UIReport_177.html specify a file name
or directory name on the target
(F = file, D = directory)? 
aschipfl
  • 31,767
  • 12
  • 51
  • 89
Testuser
  • 967
  • 1
  • 6
  • 14
  • 1
    In case you don't bother to go through all the details and options of `xcopy` add a [back-slash](https://www.tek-tips.com/viewthread.cfm?qid=1126822) at the end of your target path `%target\%` – mchar Jul 06 '18 at 14:15
  • @mchar, but then you have to move it one place beack like `%target%\ `(so behind the closing `%`)... – aschipfl Mar 17 '20 at 21:08

7 Answers7

106

The /I switch (not /F as you mentioned in your question) prevents xcopy from asking whether the destination is a file or a directory only if multiple source files are given, so if the source is a directory, or if wildcards ? or * are used. If the destination already exists, such prompt does never appear.

There are the following scenarios (depending on the provided values of %source% and %target%):

  • a single source file, the destination is a file:

    the /I switch is useless, so you need to pipe F into the xcopy command line:

    echo F|xcopy /S /Q /Y /F "%source%" "%target%"
    

    provided that the /Y switch is given (to force overwriting), you could also create the target file in advance (empty file):

    >> "%target%" rem/
    xcopy /S /Q /Y /F "%source%" "%target%"
    
  • a single source file, the destination is a directory:

    the /I switch is useless too; you can pipe D into the xcopy command line:

    echo D|xcopy /S /Q /Y /F "%source%" "%target%"
    

    or you can simply append a \ to the destination:

    xcopy /S /Q /Y /F "%source%" "%target%\"
    

    although this causes trouble when %target% specifies the current directory of a drive like D: for instance, because D: means the current directory of this drive whereas D:\ means the root directory of it;

    or you create the destination directory in advance:

    2> nul mkdir "%target%"
    xcopy /S /Q /Y /F "%source%" "%target%"
    

    the 2> nul portion suppresses the error message in case the directory already exists;

  • multiple source files, the destination is a file:

    this is usually a senseless situation, because you tell xcopy to copy each source file to the same destination file, thus attempting to overwrite it;

  • multiple source files, the destination is a directory:

    the /I switch makes sense here:

    xcopy /S /I /Q /Y /F "%source%" "%target%"
    

    the pipe option also works here:

    echo D|xcopy /S /Q /Y /F "%source%" "%target%"
    

    so does appending a \ to the destination (regarding the limitation as mentioned above):

    xcopy /S /Q /Y /F "%source%" "%target%\"
    

    or you create the destination directory in advance:

    2> nul mkdir "%target%"
    xcopy /S /Q /Y /F "%source%" "%target%"
    

Conclusion

The most flexible and secure solution is to pipe the desired selection (F or D) into the xcopy command line. (Note that the query is locale-dependent.)


Supplement

There are some minor issues in your code fragment I want to mention here:

  • you should generally use the \ as a path separator as this is the Windows standard character for that purpose (although / works too in most cases);
  • there is -1111 appended to your second net use command line; if this constitutes the password for the resource, it should be moved before the /USER option; otherwise just remove it;
  • your set command lines introduce problems with some special characters (like &, ^, (, )); to avoid such, state set "source=%~1" and set "target=p:/%~2"; the ~ removes potential surrounding "" from the arguments (which are required if they contain SPACE, ,, ;, =);

Here is the code with the all of the above things reworked:

net use P: /DELETE
rem supposing `-1111` constitutes the password for the resource:
net use P: "\\200clan\F_Drive" -1111 /USER:adm /PERSISTENT:NO

set "source=%~1"
set "target=P:\%~2"

echo "%source%" "%target%"

rem supposing the destination is a directory:
echo D|xcopy /S /I /Q /Y /F "%source%" "%target%"


rem actually you do not need any interim variables:
REM echo D|xcopy /S /I /Q /Y /F "%~1" "P:\%~2"
aschipfl
  • 31,767
  • 12
  • 51
  • 89
  • 10
    Very good answer. I just want to add that `F` for __file__ and `D` for __directory__ are only the right characters on English Windows. For example on a German Windows `D` is for a file (German: Datei) and `V` is for a directory (German: Verzeichnis). If an OS language independent solution is needed for copying a single file with `xcopy` which can't be copied with `copy`, look on batch code on [this answer on BATCH file asks for file or folder](http://stackoverflow.com/a/35829012/3074564). – Mofi Nov 12 '16 at 10:36
  • Adding the slash to the end of the target directory fixed it for me. It no longer asks if the path is a file or directory. Thanks! – Josh P Dec 06 '19 at 16:56
  • 1
    My Solution was simple: Replace XCOPY for COPY command, ejem: COPY "%source%" "%target%" /Y – Jhollman Sep 19 '20 at 14:15
  • Sure, @Jhollman, `copy` doesn't prompt for file/dir.; it has way less options though, so it might not be adequate for some situations… – aschipfl Sep 19 '20 at 14:21
  • Very good answer. But be aware there is a localization issue with that - it works for englisch Windows versions, but for example on a German Windows it will be "d = file (datei), v = directory (verzeichnis)", so you would write `echo d | xcopy 23.txt 24.txt` instead. – Matt Jul 06 '21 at 08:39
80

Put a \ behind the target to suppress the question and specify it as a folder:

xcopy src dest\

Put a * behind the target to suppress the question and specify it as a file:

xcopy src dest*

Note: The second command is a hack that relies on wildcard matching (will match any item starting with "dest") so use it at your own risk!

xjcl
  • 9,368
  • 5
  • 53
  • 64
Paul
  • 801
  • 6
  • 2
  • 3
    I keep seeing this as a suggestion and I have to say after testing it, it doesn't work as advertised. The wildcard (*) is still a wildcard so it will try to match anything that starts with file2 (using the same example above). I recommend using the piping method instead which is kind of silly, but it works. I wish that there was a switch that just said "It's always a file" or "It's always a directory". – dyslexicanaboko Aug 29 '19 at 18:36
16

xcopy doesn't know the target is a directory. You clarify this by putting a backslash at the end:

xcopy /S /I /Q /Y /F "%source%" "%target%\"
Dominique
  • 13,061
  • 14
  • 45
  • 83
  • 1
    This helped my situation, even though it is technically not the correct answer for the original post. The example target variable included the full path plus filename, so adding a backslash at the end will only confuse things for the original poster. If the `source` is a _single file_ and the `target` is a _folder_, as it is in my case, adding the backslash to the target and using the `/i` switch made the File/Directory question go away and the directory was then correctly presumed. – Mark Nov 08 '18 at 16:29
11

When copying a single file with XCOPY, there is no option to indicate if the destination is a filename or a directory (with the filename defaulting to that of the source file). In such cases XCOPY will prompt with a (locale specific) message like:

C:> xcopy foo.txt bar.txt

it prompts Does foo.txt specify a file name or directory name on the target (F = file, D = directory)?

Adding a wildcard (*) to the end of the destination will suppress this prompt and default to copying as a file:

C:> xcopy foo.txt bar.txt* 1 File(s) copied

This requires the source and target file extensions to be the same length, typically 3 characters.

for more information: https://ss64.com/nt/xcopy.html

Mizan Shamu
  • 111
  • 1
  • 4
0

I use:

xcopy /S /I /Q /Y /F "%source%" "%target%"

It works.

Pang
  • 9,073
  • 146
  • 84
  • 117
  • The help (xcopy /?) shows that /Q and /F are opposites: /Q: Does not display file names while copying; /F: Displays full source and destination file names while copying. – Adam Mester Jul 08 '21 at 07:28
0

Try:

echo F>xcopy_answer.tmp
xcopy xcopy /Q/Y "%source%" "%target%"<xcopy_answer.tmp
nhatkhai
  • 1
  • 1
-1

Removing the destination filename will suppress the message. This works for me!

Divs
  • 1