Передать путь с пробелами в качестве параметра в файл bat
У меня есть простой скрипт bat, который копирует файлы из известного каталога в каталог, указанный пользователем. Как я могу передать путь (он может содержать пробелы) своему скрипту и использовать его с помощью команды xcopy?
В моем коде есть следующее
:READ_PWA_PATH
if "%1" == "" (
rem Set default path
set PWA_PATH="C:Program FilesPWA"
rem
echo You have not specified your PWA url.
echo Default will be assumed: C:Program FilesPWA.
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:ProjectsSetup>install.cmd "C:program files (x86)"
-----------------
SETUP SCRIPT
-----------------
files was unexpected at this time.
C:ProjectsSetup>
7 ответов:
Интересная штука. Я люблю собирать цитаты об обработке цитат в cmd / command.
Ваши скрипты исправляются с помощью %1 вместо "%1"!!!
Добавив 'echo on' (или избавившись от echo off ), вы легко могли бы это выяснить.
Используйте
"%~1".%~1самостоятельно удаляет окружающие кавычки. Однако, поскольку вы не можете знать, содержит ли входной параметр%1кавычки или нет, вы должны убедиться с помощью"%~1", что они добавлены наверняка. Это особенно полезно при объединении переменных, напримерconvert.exe "%~1.input" "%~1.output"
Я думаю, что проблема ОП заключалась в том, что он хочет сделать оба из следующего:
- передайте параметр, который может содержать пробелы
- проверьте, отсутствует ли параметр
Как уже упоминалось в нескольких плакатах, чтобы передать параметр, содержащий пробелы, вы должны окружить фактическое значение параметра двойными кавычками.
Чтобы проверить, отсутствует ли параметр, я всегда изучал метод:
if "%1" == ""Однако, если фактический параметр равен в кавычках (как и должно быть, если значение содержит пробелы), это становится
if ""actual parameter value"" == "", что приводит к" неожиданной " ошибке. Если вы вместо этого используете
if %1 == ""Тогда ошибка больше не возникает для котируемых значений. Но в этом случае тест больше не работает , когда значение отсутствует - он становится
if == ""Чтобы исправить это, используйте любые другие символы (кроме тех, которые имеют особое значение для DOS) вместо кавычек в тесте:
if [%1] == [] if .%1. == .. if abc%1xyz == abcxyz
"%~1" будет работать большую часть времени. Однако есть несколько вещей, которые вы должны отметить для этого:
- он не поддерживается в Windows NT 4.0. Вам нужна Windows 2000 или более поздней версии. (Если вы пишете сценарий, совместимый со старой ОС, будьте осторожны.)
- это не делает параметры безопасными и дезинфицированными. Мое наблюдение состоит в том, что нет никакого способа должным образом очистить аргументы командной строки в сценариях 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 будет выполнена два раза, один сразу после набора, а другой сразу после первое эхо. Вы видите, что"%~1", которое вы считаете хорошо цитируемым, не цитируется самим аргументом.Таким образом, нет никакого способа сделать парсинг аргументов безопасным.
(EDIT:
EnableDelayedExpansionтакже не работает в Windows NT 4. Спасибо за информацию здесь: http://www.robvanderwoude.com/local.php )
Если у вас есть путь с пробелами, вы должны окружить его кавычками (").
Не уверен, что это именно то, о чем вы спрашиваете?
@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Как упоминает Вардхандотнет,
%1достаточно.
"%1%"добавлял бы кавычки вокруг кавычек:""c:\Program Files\xxx"", Что означает:
- 'пустая строка' (
""),- далее следует 'c:\Program',
- далее следует "неожиданный здесь "'Files\xxx',
- , за которым следует пустая строка (
"")Обратите внимание, однако, что если вам нужно использовать
PWA_PATHв вашем предложенииIF, Вы должны ссылаться if как!PWA_PATH!(следовательно,enabledelayedexpansionкак начало сценарий)
Если ваш путь содержит пробел, то попробуйте использовать
%~s1. Это удалит пробел и добавит~1к вашему пути, и что более важно, это относится к абсолютному пути вашего файла. Попробуйте использовать его.
Comments