Ответ 1
Интересный. Мне нравится собирать цитаты о обработке кавычек в команде cmd/.
Ваши конкретные скрипты фиксируются с помощью% 1 вместо "% 1"!!!
Добавив "echo on" (или избавившись от эха), вы могли бы легко найти это.
У меня есть простая bat script, которая копирует файлы из известного каталога в каталог, заданный пользователем. Как передать путь (он может содержать пробелы) на мой script и использовать его с помощью команды 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
)
Если я просто вызываю script, я получаю следующую ошибку:
C:\Projects\Setup>install.cmd "C:\program files (x86)"
-----------------
SETUP SCRIPT
-----------------
files was unexpected at this time.
C:\Projects\Setup>
Интересный. Мне нравится собирать цитаты о обработке кавычек в команде cmd/.
Ваши конкретные скрипты фиксируются с помощью% 1 вместо "% 1"!!!
Добавив "echo on" (или избавившись от эха), вы могли бы легко найти это.
Используйте "%~1"
. %~1
только удаляет окружающие кавычки. Однако, поскольку вы не можете знать, имеет ли входной параметр %1
кавычки или нет, вы должны убедиться, что "%~1"
уверены, что они добавлены. Это особенно полезно при объединении переменных, например. convert.exe "%~1.input" "%~1.output"
Литература:
Я думаю, что проблема с OP заключалась в том, что он хочет сделать ОБА из следующего:
Как упоминалось несколькими плакатами, чтобы передать параметр, содержащий пробелы, вы должны окружить фактическое значение параметра двойными кавычками.
Чтобы проверить, отсутствует ли параметр, метод, который я всегда изучал, был:
if "%1" == ""
Однако, если фактический параметр указан (как и должно быть, если значение содержит пробелы), это становится
if ""actual parameter value"" == ""
который вызывает "неожиданную" ошибку. Если вы используете
if %1 == ""
тогда ошибка больше не возникает для цитируемых значений. Но в этом случае тест больше не работает, когда значение отсутствует - оно становится
if == ""
Чтобы исправить это, используйте любые другие символы (кроме символов со специальным значением для DOS) вместо кавычек в тесте:
if [%1] == []
if .%1. == ..
if abc%1xyz == abcxyz
Если у вас есть путь с пробелами, вы должны окружить его кавычками (").
Не уверен, что именно это вы спрашиваете?
"% ~ 1" будет работать большую часть времени. Однако есть несколько вещей, которые вам нужно отметить для этого:
Чтобы продемонстрировать вторую точку, позвольте мне привести пример:
REM example.cmd
ECHO %~1
Выполнить с example.cmd dummy^&DIR
. Амперсанд скрывается здесь (^&
), чтобы интерпретировать интерпретатор оболочки как разделитель команд, чтобы он стал частью аргумента, переданного в script. DIR интерпретируется как команда внутри суб-оболочки, запускающей script, где он не должен.
Цитата: это может сработать некоторое время, но все еще небезопасно:
REM example2.cmd
SETLOCAL EnableExtensions EnableDelayedExpansion
SET "arg1=%~1"
ECHO "%~1"
ECHO !arg1:"=!
example2.cmd foo^"^&DIR^&^"bar
сломает его. Команда DIR будет запускаться два раза, один сразу после SET, а другой сразу после первого ECHO. Вы видите, что "%~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
Как VardhanDotNet упоминает, %1
достаточно.
"%1%"
добавит кавычки вокруг кавычек: ""c:\Program Files\xxx""
, что означает:
""
),""
)Обратите внимание, что если вам нужно использовать PWA_PATH
в вашем предложении IF
, вам нужно указать if as !PWA_PATH!
(следовательно, enabledelayedexpansion
в качестве начала script)
Если ваш путь содержит пробел, попробуйте использовать %~s1
. Это удалит пространство и добавит ~1
к вашему пути, и, что более важно, это относится к абсолютному пути вашего файла. Попробуйте использовать его.