Передать путь с пробелами в качестве параметра в файл bat - PullRequest
55 голосов
/ 23 января 2009

У меня есть простой скрипт bat, который копирует файлы из известного каталога в каталог, указанный пользователем. Как я могу передать путь (он может содержать пробелы) в мой скрипт и использовать его с командой xcopy?


В моем коде у меня есть следующее

:READ_PWA_PATH
    if "%1" == "" ( 
        rem Set default path
        set PWA_PATH="C:\Program Files\PWA"
        rem
        echo You have not specified your PWA url.
        echo Default will be assumed: C:\Program Files\PWA. 
        choice /C:YN /M:"Do you wish to continue [Y] or cancel the script [N]?"
            IF ERRORLEVEL ==2 GOTO CANCEL
            IF ERRORLEVEL ==1 GOTO READ_WSS_SERVER_EXTENSIONS_PATH
        GOTO END
    ) else (
        set PWA_PATH=%1
    )

Если я просто вызываю скрипт, я получаю следующую ошибку:

C:\Projects\Setup>install.cmd "C:\program files (x86)"

-----------------
SETUP SCRIPT
-----------------

files was unexpected at this time.
C:\Projects\Setup>

Ответы [ 7 ]

99 голосов
/ 08 декабря 2010

Используйте "%~1". %~1 один удаляет окружающие кавычки. Однако, поскольку вы не можете знать, имеет ли входной параметр %1 кавычки или нет, вы должны "%~1" убедиться, что они добавлены наверняка. Это особенно полезно при объединении переменных, например, convert.exe "%~1.input" "%~1.output"

20 голосов
/ 23 января 2009

Интересный. Я люблю собирать цитаты об обработке кавычек в cmd / command.

Ваши конкретные сценарии исправляются с помощью% 1 вместо "% 1" !!!

Добавив 'echo on' (или избавившись от echo off), вы могли легко это выяснить.

14 голосов
/ 05 мая 2009

Я думаю, что проблема ОП заключалась в том, что он хочет ОБА следующего:

  • Передать параметр, который может содержать пробелы
  • Проверить, отсутствует ли параметр

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

Чтобы проверить, отсутствует ли параметр, я всегда изучал метод:

if "%1" == ""

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

if ""actual parameter value"" == ""

, который вызывает «неожиданную» ошибку. Если вы вместо этого используете

if %1 == ""

тогда ошибка больше не возникает для указанных значений. Но в этом случае тест больше не работает , когда значение отсутствует - оно становится

if  == ""

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

if [%1] == []
if .%1. == ..
if abc%1xyz == abcxyz
6 голосов
/ 06 марта 2015

"% ~ 1" будет работать большую часть времени. Однако для этого нужно отметить несколько вещей:

  1. Это не поддерживается в Windows NT 4.0. Вам нужна Windows 2000 или более поздняя версия. (Если вы кодируете скрипт, совместимый со старой ОС, будьте осторожны.)
  2. Это не делает параметры безопасными и очищенными. Мое наблюдение состоит в том, что нет способа должной очистки параметров командной строки в сценариях CMD.

Для демонстрации второго пункта приведу пример:

REM example.cmd
ECHO %~1

Запуск с example.cmd dummy^&DIR. Здесь амперсанд экранирован (^&), чтобы не интерпретировать оболочку как разделитель команд, чтобы он стал частью аргумента, передаваемого сценарию. DIR интерпретируется как команда внутри вложенной оболочки, выполняющей сценарий , где она не должна.

Цитирование может работать некоторое время, но все еще небезопасно:

REM example2.cmd
SETLOCAL EnableExtensions EnableDelayedExpansion
SET "arg1=%~1"
ECHO "%~1"
ECHO !arg1:"=!

example2.cmd foo^"^&DIR^&^"bar сломает его. Команда DIR будет выполняться два раза, один сразу после SET, а другой сразу после первого ECHO. Вы видите, что "%~1", который вы считаете хорошо процитированным, не цитируется самим аргументом.

Таким образом, невозможно обеспечить безопасность анализа аргументов.

(РЕДАКТИРОВАТЬ: EnableDelayedExpansion также не работает в Windows NT 4. Благодаря информации здесь: http://www.robvanderwoude.com/local.php)

5 голосов
/ 23 января 2009

Если у вас есть путь с пробелами, вы должны заключить его в кавычки (").

Не уверен, что это именно то, что вы спрашиваете?

2 голосов
/ 31 августа 2012

Если ваш путь содержит пробел, попробуйте использовать %~s1. Это удалит пробел и добавит ~1 к вашему пути и, что более важно, относится к абсолютному пути вашего файла. Попробуйте использовать его.

2 голосов
/ 23 января 2009
@echo off
setlocal enableextensions enabledelayedexpansion

if %1=="" (     
        rem Set default path
        set PWA_PATH="C:\Program Files\PWA"
        rem
        echo You have not specified your PWA url.
        echo Default will be assumed: C:\Program Files\PWA.     
        choice /C:YN /M:"Do you wish to continue [Y] or cancel the script [N]?"
                IF ERRORLEVEL ==2 GOTO CANCEL
                IF ERRORLEVEL ==1 GOTO READ_WSS_SERVER_EXTENSIONS_PATH
        GOTO END
    ) else (
        set PWA_PATH=%1
        @echo !PWA_PATH! vs. %1
        goto end
    )
:READ_WSS_SERVER_EXTENSIONS_PATH
echo ok
goto end
:CANCEL
echo cancelled
:end
echo. final %PWA_PATH% vs. %1

Как отмечает VardhanDotNet , достаточно %1.

"%1%" добавит кавычки вокруг кавычек: ""c:\Program Files\xxx"", что означает:

  • 'пустая строка' (""),
  • с последующим «c: \ Program»,
  • с последующим «неожиданным здесь», «Файлы \ xxx»,
  • , за которым следует пустая строка ("")

Обратите внимание, однако, что если вам нужно использовать PWA_PATH в вашем предложении IF, вам нужно ссылаться, если !PWA_PATH! (отсюда enabledelayedexpansion как начало сценария)

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