Цитирование пакетных аргументов Windows, которые могут заканчиваться обратной косой чертой - PullRequest
0 голосов
/ 01 июля 2018

Мне нужно процитировать произвольные аргументы в пакетном файле Windows 10, и у меня возникают проблемы, когда они заканчиваются обратной косой чертой.

Допустим, я хочу позвонить в Robocopy, чтобы скопировать *.foo файлы из A:\ в B:\ следующим образом:

robocopy A:\ B:\ *.foo

Но на самом деле я получаю A:\ в качестве аргумента (скажем, я использую %~1, и я не знаю, содержит ли он пробелы, поэтому я цитирую это:

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

К сожалению, если %SOURCE% заканчивается обратной косой чертой, последний \ считается escape-символом, экранирующим ".

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

Таким образом, Windows считает, что первый аргумент "A:" B:\ *.foo.

Как отключить интерпретацию \" как escape-последовательности?

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

Я предлагаю использовать командный файл, как этот командный файл с комментариями:

@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.
goto :EOF

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

Чтобы понять используемые команды и то, как они работают, откройте окно командной строки, выполните там следующие команды и полностью прочитайте все страницы справки, отображаемые для каждой команды.

  • call /?
  • cls /?
  • echo /?
  • goto /?
  • if /?
  • pause /?
  • rem /?
  • robocopy /?
  • set /?
0 голосов
/ 01 июля 2018

Это просто! Вам нужно сбежать от побега персонажа! Когда вы используете \\ вместо \, первая обратная косая черта экранируется от второй, и больше ничего не экранируется.

Итак, при выполнении вашей команды вы должны использовать это:

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

Также ничего не стоит, что robocopy работает, даже если вы не заканчиваете пути обратной косой чертой. Таким образом, вы также можете просто использовать это:

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

Если вы не знаете, заканчивается ли путь обратной косой чертой (например, если вы берете его у пользователя), вы можете использовать эту команду для удаления всех обратных косых черт в пути:

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

После чего вы можете запускать robocopy как обычно, используя %SOURCE% в качестве аргумента, даже если он заканчивается обратной косой чертой!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...