Передать путь с пробелами в качестве параметра в файл 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>
665   7  

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" будет работать большую часть времени. Однако есть несколько вещей, которые вы должны отметить для этого:

  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 будет выполнена два раза, один сразу после набора, а другой сразу после первое эхо. Вы видите, что "%~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

    Ничего не найдено.