Работа с кавычками в пакетных скриптах Windows - PullRequest
55 голосов
/ 11 февраля 2009

В пакетном файле Windows, когда вы делаете следующее:

set myvar="c:\my music & videos"

переменная myvar сохраняется с включенными кавычками. Честно говоря, я нахожу это очень глупым. Кавычки просто указывают, где начинается и заканчивается строка, а не хранятся как часть самого значения.
Как я могу предотвратить это?

Спасибо.

Ответы [ 7 ]

59 голосов
/ 20 октября 2012

Это правильный способ сделать это:

set "myvar=c:\my music & videos"

Кавычки не будут включены в значение переменной.

50 голосов
/ 21 декабря 2011
set "myvar=c:\my music & videos"

Обратите внимание, что кавычки начинаются до myvar. Это на самом деле так просто. Примечание: myvar не может быть отображен впоследствии, если он не заключен в кавычки, потому что & будет читаться как разделитель команд, но все равно будет работать как путь.

http://ss64.com/nt/set.html в разделе «Имена переменных могут включать пробелы»

35 голосов
/ 11 февраля 2009

Это зависит от того, как вы хотите использовать переменную. Если вы просто хотите использовать значение переменной без кавычек, вы можете использовать либо отложенное раскрытие и подстановку строк, либо команду for:

@echo OFF
SETLOCAL enabledelayedexpansion

set myvar="C:\my music & videos"

Как говорится в andynormancx, кавычки необходимы, поскольку строка содержит &. Или вы можете избежать этого с помощью ^, но я думаю, что цитаты немного чище.

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

@echo !myvar:"=!
>>> C:\my music & videos

Вы также можете использовать команду for:

for /f "tokens=* delims=" %%P in (%myvar%) do (
    @echo %%P
)
>>> C:\my music & videos

Однако, если вы хотите использовать переменную в команде, вы должны использовать значение в кавычках или заключить значение переменной в кавычки:

  1. Использование подстановки строк и отложенного раскрытия для использования значения переменной без кавычек, но использование переменной в команде:

    @echo OFF
    SETLOCAL enabledelayedexpansion
    
    set myvar="C:\my music & videos"
    md %myvar%
    @echo !myvar:"=! created.
    
  2. Использование команды for для использования значения переменной без кавычек, но вам придется заключать переменную в кавычки при использовании ее в командах:

    @echo OFF
    set myvar="C:\my music & videos"
    
    for /f "tokens=* delims=" %%P in (%myvar%) do (
        md "%%P"
        @echo %%P created.
    )
    

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

6 голосов
/ 11 февраля 2009

Используйте jscript.

Много лун назад (т. Е. Около 8 лет), я работал над большим проектом C ++ / VB6, и у меня были различные фрагменты Batch Script для выполнения частей сборки.

Затем кто-то указал мне на Joel Test , я был особенно очарован пунктом 2 и принялся за объединение всех моих маленьких сценариев сборки в один единственный сценарий сборки. , .

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

В конце концов - я могу быть упрямым - Я забросил всю партию и примерно за день переписал все это на JavaScript , запустив его из командной строки с помощью CScript .

Я не оглядывался назад. Хотя в наши дни это MSBuild и Cruise Control, если мне нужно что-то сделать, даже немного связанное с пакетным скриптом, я использую jscript.

2 голосов
/ 11 ноября 2016

Интерпретатор команд Windows позволяет использовать кавычки вокруг всей команды set (действует в каждой версии Windows NT от NT 4.0 до Windows 2012 R2)

Ваш сценарий должен быть написан следующим образом:

@echo OFF

set "myvar=C:\my music & videos"

Затем вы можете заключать в кавычки переменные по мере необходимости.

Работа с приглашением CMD иногда может показаться эзотерической, но интерпретатор команд на самом деле ведет себя довольно твердо, подчиняясь своей внутренней логике, вам просто нужно переосмыслить вещи.

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

например. Оба из нижеприведенных являются технически действительными, но вы можете иметь пробелы, поэтому это не очень хорошая практика:

set myvar=some text   
set myvar="some text" 

например. Оба нижеприведенных метода являются хорошими для установки переменных в интерпретаторе команд Windows, однако метод двойных кавычек лучше:

set "myvar=Some text"
(set myvar=Some value)

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

сильный текст Однако, для ваших целей, только указанный метод будет работать корректно, потому что вы используете зарезервированный символ

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

set myvar="c:\my music & videos"

Однако, хотя переменная IS правильно установлена ​​на эту строку, когда вы выводите ECHO, строка интерпретатора команды будет интерпретировать амперсанд как ключевое слово для обозначения следующего оператора.

ТАК, если вы хотите вывести строку из переменной, интерпретатору CMD все равно нужно сообщить, что это текстовая строка, или если вы не хотите, чтобы в кавычках показывалось, вам нужно выполнить одно из следующих действий:

выводит переменную WITH Quotes:

Echo."%myvar%"

выводит переменную БЕЗ Кавычек:

Echo.%myvar:&=^&%
<nul SET /P="%myvar%"

В двух приведенных выше сценариях вы можете просто повторить строку без кавычек. Пример вывода ниже:

C:\Admin>    Echo.%myvar:&=^&%
C:\my music & videos

C:\Admin>    <nul SET /P="%myvar%"
C:\my music & videos
C:\Admin>
1 голос
/ 11 февраля 2009

Попробуйте использовать escape-символ '^', например

set myvar=c:\my music ^& videos

Вы будете осторожны при расширении myvar, потому что оболочка может не воспринимать & как литерал. Если вышеприведенное не работает, попробуйте вставить каркас в строку:

set myvar=c:\my music ^^^& videos
1 голос
/ 11 февраля 2009

Вы должны иметь кавычки, если текст, который вы устанавливаете, содержит определенные символы, включая & . Если ваш текст не содержит & , тогда вам не нужны кавычки.

Например, если бы текст был просто "c: \ my music", вы могли бы сделать:

set myvar = c:\my music

Но поскольку в вашем тексте есть & , вам нужны кавычки.

Edit:

Или, как говорит Дейв в своем ответе, вы можете избежать проблемных символов с помощью ^^^ , но остерегайтесь такого подхода, так как & - не единственный символ, который вам нужен , На практике гораздо проще придерживаться кавычек, чем избегать всех проблемных символов.

...