Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I just need to ask if this is expected behaviour, it sure surprised me.

We have a batch file that copies some files from a sub-directory of where it is located, to another location on every developers machine. Since for some developers, this target directory differs from the rest, we've set a user environment variable, and used that in the batch file.

This is a sample line from the batch file:

ROBOCOPY Staging\*.* "%DISTRIBUTE_TARGET%" *.* /IS

This failed on one machine, and after some experimentation, it dawned on me that on this machine, the variable had a trailing backslash as part of the variable content.

On most machines (in fact, all the other machines, where it worked), the variable looked like this:

DISTRIBUTE_TARGET=C:\Some\Directory

but on this machine, it was:

DISTRIBUTE_TARGET=C:\Some\Directory\

notice the added backslash there.

The error message given by ROBOCOPY was that there was something wrong with the second parameter, but it seemed to think that everything from the start of that variable, and to the end of the line, was all in the 2nd parameter.

Ie. the error message looked like this:

Error in second parameter: "C:\Some\Directory\" *.* /IS"

What I assume happened is that the backslash "escaped" the quote character, which removed its meaning as "end of quoted parameter", and thus the rest of the line was just grabbed as part of the argument.

Is this expected behavior? Does this mean that variables with a trailing backslash, for whatever reason or purpose, just cannot be safely used?

share|improve this question

2 Answers 2

up vote 2 down vote accepted

From this article:

If either the source or destination are a "quoted long foldername" do not include a trailing backslash as this will be treated as an escape character, i.e. "C:\some path\" will fail but "C:\some path\\" or "C:\some path" will work.

This is a problem specific to robocopy. I would even go as far as to call it a bug.

You have no other solution but to add code to your batch file that will check and delete a backslash from the end of the source and destination.

share|improve this answer
1  
Wrong. This is a bug-sold-as-feature in Windows shell variable expansion. Why is this marked as answer!? –  Daniel Dinnyes Jun 28 '13 at 13:39
    
@DanielDinnyes: My explanation above is actually correct, since the analysis of the command-line is done by robocopy and not by Windows. Windows uses the back-slash as the directory separator and doesn't have an escape-character. The analysis routine of robocopy was probably taken from Linux and sees an escape-character where there is none, so treats the \" as " that is included in the string. So it continues the string up to the next ", gets confused, and generates an error. –  harrymc Jun 28 '13 at 14:04
    
As the above was written in 2010, this problem might not still exist today in robocopy. –  harrymc Jun 28 '13 at 14:08
1  
Your explanation is actually not correct. The correct answer is below from @Kevin. This has nothing to do with robocopy. The shell script the OP wrote has the problem, as robocopy receives "C:\Some\Directory\" *.* /IS" as second argument from the shell. It is not the bug in robocopy that the second string is not recognized as a valid path. –  Daniel Dinnyes Jun 28 '13 at 14:19
1  
@harrymc, my apologies, i am late a few months with my response. :) But anyway... Do not try with the dir command, as it is not an executable. Try starting an *.exe file, passing some arguments where the 1st is like "c:\folder\". Windows screws this up when it is passing the arguments to the new process... –  elgonzo Nov 14 '13 at 18:51

Indeed this is not specific to robocopy, but rather the CommandLineToArgvW Windows API function.

CommandLineToArgvW has a special interpretation of backslash characters when they are followed by a quotation mark character ("), as follows:

2n backslashes followed by a quotation mark produce n backslashes followed by a quotation mark.

(2n) + 1 backslashes followed by a quotation mark again produce n backslashes followed by a quotation mark.

n backslashes not followed by a quotation mark simply produce n backslashes.

The same rules are described in Parsing C++ Command-Line Arguments

A workaround is to append . to everything you know is a directory (e.g. "C:\Program Files\.")

share|improve this answer
    
I would add \. to the end instead. Has the same effect, but it is less confusing, therefore error prone. Having a . at the end of directory name is stripped of during file system navigation and operations, but it could cause problems if some program you pass it to tries to do something with it without being aware of the dot-stripping done by Windows. This stuff is arcane! –  Daniel Dinnyes Jun 28 '13 at 14:13
    
Be careful: \. is not the same as \\.. (The latter is interpreted as an invalid UNC path) –  Kevin Smyth Jul 25 at 19:28

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.