6

I need to quote arbitrary arguments in a Windows 10 batch file, and I'm having problems when they end in a backslash.

Let's say I want to call Robocopy to copy *.foo files from A:\ to B:\ like this:

robocopy A:\ B:\ *.foo

But really I'm getting A:\ as an argument (let's say I use %~1, and I don't know if it contains spaces, so I quote it:

robocopy "%SOURCE%" B:\ *.foo

Unfortunately if %SOURCE% ends with a backslash, the last \ is considered an escape character, escaping ".

robocopy "A:\" B:\ *.foo

So Windows thinks the first argument is "A:" B:\ *.foo.

How can I turn off interpretation of \" as an escape sequence?

3
  • 1
    But \ isn't an escape character in batch... is this some weird functionality of robocopy that I'm not aware of? Commented Jul 1, 2018 at 18:28
  • 1
    @SomethingDark Yes, ROBOCOPY is different in comparison to most other commands and interprets a trailing backslash as escape character. Documentation of robocopy on ss64.com warns about a special handling of a trailing backslash by ROBOCOPY. Commented Jul 1, 2018 at 19:29
  • 1
    @SomethingDark REG is another command which interprets a trailing backslash as an escape character as it can be seen by running twice reg add "HKCU\Environment" /v MyRegTest /t REG_SZ /d "%TEMP%\" /f. The user is prompted on second run although there is /f at end. But run reg query "HKCU\Environment" /v MyRegTest and it can be seen what was really added on first run. Run last reg delete "HKCU\Environment" /v MyRegTest /f to remove the added user environment variable with a value ending with " /f not expected by most users. Commented Jul 1, 2018 at 19:33

2 Answers 2

3

It's simple! You need to escape the escape character! When you use \\ instead of \, the first backslash escapes the second, and nothing further is escaped.

So, while running your command, you should use this:

<command> "this\is\a\path\\" "\this\is\another\path\\"

It is also worth nothing that robocopy works even if you don't end the paths with backslashes. So you can also totally just use this:

robocopy "this\is\a\path" "this\is\another\path" <args>

If you don't know whether or not the path ends with a backslash (for example if you're taking it from a user), you can use this command to escape all backslashes in the path:

%SOURCE%=%SOURCE:\=\\% 

After which you can run robocopy normally using %SOURCE% as an argument, even if it ends with a backslash!

Sign up to request clarification or add additional context in comments.

3 Comments

I'm running robocopy from within a batch file. I don't want the user of the batch file to need to escape things on the command line.
Even though robocopy works if you don't end the paths without backslashes, B:\ and B: are two very different things; the second is relative to the current directory.
@GarretWilson See the last solution, %SOURCE%=%SOURCE:\=\\% is what you need
0

I suggest using a batch file like this commented one:

@echo off
if not exist %SystemRoot%\System32\robocopy.exe goto BatchHelp
if "%~1" == ""   goto BatchHelp
if "%~1" == "/?" goto BatchHelp
if "%~2" == ""   goto BatchHelp

call :CleanPath SOURCE %1
call :CleanPath DESTINATION %2

%SystemRoot%\System32\robocopy.exe "%SOURCE%" "%DESTINATION%" *.foo

rem Delete the used environment variables.
set "SOURCE="
set "DESTINATION="

rem Avoid a fall through to the subroutine CleanPath.
exit /B

rem The subroutine CleanPath must be called with two arguments.
rem The first one must be the environment variable which should hold the
rem cleaned folder path for usage with ROBOCOPY. The second argument must
rem be the folder path which should be cleaned for usage with ROBOCOPY.

:CleanPath
rem Get full absolute path of folder path. This reduces a lot of variants
rem which could occur on batch file called with various relative paths.
set "FolderPath=%~f2"

rem Does the folder path not end with a backslash?
if not "%FolderPath:~-1%" == "\" goto HavePath

rem Does the folder path have just three characters and is ending with
rem a colon and a backslash? Yes, append an escaping backslash at end.
rem Otherwise the folder path of a folder not being the root folder
rem of a drive ends with a backslash which must be removed to get
rem the folder path correct interpreted by ROBOCOPY.
if "%FolderPath:~1%" == ":\" (
    set "FolderPath=%FolderPath%\"
) else (
    set "FolderPath=%FolderPath:~0,-1%"
)

:HavePath
set "%~1=%FolderPath%"
set "FolderPath="

rem Return to calling routine.
goto :EOF


:BatchHelp
cls
echo Usage: %~nx0 source destination
echo(
echo        source ... source directory
echo   destination ... destination directory
echo(
echo This batch file requires ROBOCOPY in Windows system directory.
echo(
pause

To understand the commands used and how they work, open a command prompt window, execute there the following commands, and read the displayed help pages for each command, entirely and carefully.

  • call /?
  • cls /?
  • echo /?
  • exit /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • robocopy /?
  • set /?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.