it-swarm.com.ru

Передать путь с пробелами в качестве параметра в файл bat

У меня есть простой скрипт 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>
55
kjv

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

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

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

20
vrdhn

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

99
zikaS

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

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

Чтобы продемонстрировать второй пункт, позвольте мне привести пример:

REM example.cmd
ECHO %~1

Запустите с example.cmd dummy^&DIR. Здесь амперсанд экранирован (^&), чтобы предотвратить интерпретацию Shell как разделитель команд, так что он становится частью аргумента, передаваемого в сценарий. 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 )

6
Explorer09

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

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

5
user7094
@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",
  • сопровождаемый "неожиданным здесь" 'Files\xxx',
  • сопровождаемый пустой строкой ("")

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

2
VonC

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

2
Prabhu RK