Пакетный файл для циклически изменяемых аргументов? - PullRequest
9 голосов
/ 09 марта 2011

Я пытаюсь перебрать аргументы, которые я передаю в командный файл. Основываясь на аргументе, я хочу установить флаг переменной true или false для использования позже в скрипте

Итак, моя команда "myscript.bat / u / p / s"

И мой код:

FOR /f %%a IN ("%*") DO (
  IF /I "%%a"=="/u" SET UPDATE=Y
  IF /I "%%a"=="/p" SET PRIMARY=Y
  IF /I "%%a"=="/s" SET SECONDARY=Y
)

Это работает, только если у меня есть один аргумент, который говорит мне, что он получает весь список аргументов как один аргумент. Я пробовал "delims =", но безрезультатно. Есть мысли о том, чтобы получить каждый аргумент?


А как насчет добавления значения к одному из параметров?

myscript.bat / u / p / d TEST / s

:loop
IF "%~1"=="" GOTO cont
IF /I "%~1"=="/u" SET UPDATE=Y
IF /I "%~1"=="/p" SET PRIMARY=Y
IF /I "%~1"=="/s" SET SECONDARY=Y
IF /I "%~1"=="/d" SHIFT & SET DISTRO="%~1"
SHIFT & GOTO loop

:cont

Но SHIFT, который идет в линию с последним IF, на самом деле ничего не меняет. DISTRO заканчивается "/ d" вместо "TEST"

Ответы [ 2 ]

23 голосов
/ 17 октября 2012

Вы не так уж далеки от своей оригинальной пьесы, и так как я не люблю циклы GOTO, я подумал, что выложу это:

FOR %%a IN (%*) DO (
  IF /I "%%a"=="/u" SET UPDATE=Y
  IF /I "%%a"=="/p" SET PRIMARY=Y
  IF /I "%%a"=="/s" SET SECONDARY=Y
)

Причина, по которой он работал только с одним параметром, заключается вчрезмерное использование кавычек.Поместив% * в кавычки, вы делали всю командную строку одним токеном.Кроме того, вариант / F FOR не то, что вы искали.Документация доступна из FOR /?должно помочь прояснить ситуацию.

5 голосов
/ 09 марта 2011

Вы можете зациклить аргументы, используя SHIFT, GOTO и дополнительный IF, чтобы проверить, нет ли больше параметров для разбора:

:loop
IF "%~1"=="" GOTO cont
IF /I "%~1"=="/u" SET UPDATE=Y
IF /I "%~1"=="/p" SET PRIMARY=Y
IF /I "%~1"=="/s" SET SECONDARY=Y
SHIFT & GOTO loop

:cont
...

UPDATE (адресованослучай, когда у параметра есть собственный аргумент)

SHIFT в операторе IF, который проверяет /d, работает.Проблема в том, что вся строка оценивается сразу, и оба экземпляра %~1 заменяются одним и тем же значением, равным /d в этой точке.

Таким образом, в основном решение в этом случае будетзаставить переводчика оценивать часть SET DISTRO="%~1" отдельно от IF /I "%~1"=="/d".Там могут быть различные подходы к этому.Например, вы можете просто переместить SHIFT & SET DISTRO="%~1" на следующую строку и пропустить ее, если %~1 равно , а не /d:

...
IF /I NOT "%~1"=="/d" GOTO skip_d
SHIFT & SET "DISTRO=%~1"
:skip_d
...

Другим способом может быть назначение специальногозначение (например, от ?) до DISTRO и смещение при обнаружении /d.Затем на следующей строке проверьте, имеет ли DISTRO это специальное значение, и установите его на %~1:

...
IF /I "%~1"=="/d" SHIFT & SET DISTRO=?
IF "%DISTRO%"=="?" SET "DISTRO=%~1"
...
...