Как проверить параметр командной строки в файле ".bat"? - PullRequest
90 голосов
/ 10 февраля 2011

Моя ОС - Windows Vista.Мне нужно иметь файл .bat, в котором мне нужно проверить, вводит ли пользователь какой-либо параметр командной строки или нет.Если это так, если параметр равен -b, тогда я сделаю что-то другое, в противном случае я отмечу «Неверный ввод».Если пользователь не введет какой-либо параметр командной строки, я сделаю что-нибудь.Я создал следующий .bat файл.Это работает для -b и не равно -b случаев - но происходит сбой, когда пользователь не передает какой-либо параметр командной строки.

Я всегда получаю ошибку:

GOTO was unexpected at this time.

Может кто-нибудь сказать мне, что я здесь делаю не так?


ECHO OFF
CLS
ECHO.

IF [%1]==[/?] GOTO BLANK

IF %1=="-b" GOTO SPECIFIC

IF NOT %1=="-b" GOTO UNKNOWN

:SPECIFIC

ECHO SPECIFIC

GOTO DONE

:BLANK

ECHO No Parameter

GOTO DONE

:UNKNOWN

ECHO Unknown Option

GOTO DONE

:DONE

ECHO Done!

Ответы [ 6 ]

125 голосов
/ 10 февраля 2011

Необходимо проверить, не задан ли параметр: if "%~1"=="" goto blank

Как только вы это сделаете, включите параметр if / else на -b: if "%~1"=="-b" (goto specific) else goto unknown

Окружение параметров кавычками упрощает проверку таких параметров, как пустые / пустые / отсутствующие параметры. «~» гарантирует удаление двойных кавычек, если они были в аргументе командной строки.

25 голосов
/ 10 февраля 2011

Посмотрите на http://ss64.com/nt/if.html для ответа;команда IF [%1]==[] GOTO NO_ARGUMENT или аналогичная.

14 голосов
/ 09 ноября 2016

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

if [%1]==[] goto :blank

или (когда вам нужно обработать аргументы в кавычках, см. Редактирование ниже):

if [%~1]==[] goto :blank

Почему?Вы можете спросить.Ну, как сказал Иеремия Уиллкок: http://ss64.com/nt/if.html - они используют это!Хорошо, но что не так с кавычками?

Опять краткий ответ: они "магические" - иногда двойные (двойные) кавычки преобразуются в одинарные (двойные) кавычки.И для начала они должны соответствовать.

Рассмотрим этот маленький скрипт:

@rem argq.bat
@echo off

:loop 
if "%1"=="" goto :done
echo %1
shift
goto :loop

:done
echo Done.

Давайте проверим его:

C:\> argq bla bla
bla
bla
Done.

Кажется, работает.Но теперь давайте переключимся на вторую передачу:

C:\> argq "bla bla"
bla""=="" was unexpected at this time.

Стрела Это не оценивалось как истинное, равно как и ложное.Сценарий Умер.Если вы должны были выключить реактор где-то вниз по линии, ну, вам не повезло.Теперь вы умрете, как Гарри Даглиан.

Вы можете подумать - ОК, аргументы не могут содержать кавычек.Если они это сделают, это произойдет. Неправильно Вот несколько утешений:

C:\> argq ""bla bla""
""bla
bla""
Done.

О да.Не волнуйтесь - иногда это будет работать.

Давайте попробуем другой сценарий:

@rem args.bat
@echo off

:loop 
if [%1]==[] goto :done
echo %1
shift
goto :loop

:done
echo Done.

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

D:\>args ]bla bla[
]bla
bla[
Done.

D:\>args [bla bla]
[bla
bla]
Done.

Не повезло.Скобки просто не могут задушить парсер cmd.exe.

Давайте вернемся к цитатам зла на мгновение.Проблема была там, когда аргумент заканчивался кавычкой:

D:\>argq "bla1 bla2"
bla2""=="" was unexpected at this time.

Что если я передам просто:

D:\>argq bla2"
The syntax of the command is incorrect.

Сценарий не будет работать вообще.То же самое для args.bat:

D:\>args bla2"
The syntax of the command is incorrect.

Но что я получу, когда число " -символов «совпадает» (то есть - является четным), в таком случае:

D:\>args bla2" "bla3
bla2" "bla3
Done.

NICE - Я надеюсь, вы узнали кое-что о том, как .bat файлы разделяют свои аргументы командной строки (СОВЕТ: * Это не совсем так, как в bash).Приведенный выше аргумент содержит пробел.Но кавычки не удаляются автоматически.

А argq?Как это реагирует на это?Как и ожидалось:

D:\>argq bla2" "bla3
"bla3"=="" was unexpected at this time.

Итак, подумайте, прежде чем сказать: «Знаете что? Просто используйте кавычки. [Потому что, мне кажется, это выглядит лучше]».

Редактировать

В последнее время появились комментарии об этом ответе - ну, квадратные скобки «не могут обработать» передачу аргументов в кавычках и их обработку так же, как если бы они не были заключены в кавычки.

Синтаксис:

if "%~1"=="" (...)

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

Эта «технология» работает так же хорошо с квадратными скобками:

if [%~1]==[] (...)

Было полезно указать на это, поэтому я также приветствую новый ответ.

Наконец, дваждыцитируйте фанатов, существует ли в вашей книге аргумент вида "" или он пустой?Просто спрашиваешь;)

8 голосов
/ 10 февраля 2011

В дополнение к другим ответам, на которые я подписываюсь, вы можете использовать переключатель /I команды IF.

... ключ / I, если указан, говорит о необходимости сравнения строк без учета регистра.

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

IF /I "%1"=="-b" GOTO SPECIFIC
5 голосов
/ 26 октября 2017

На самом деле, все остальные ответы имеют недостатки. Самый надежный способ:

IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

Подробное объяснение:

Использование "%1"=="-b" приведет к сбою при передаче аргумента с пробелами и кавычками. Это наименее надежный метод.

IF "%1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat "a b"

b""=="-b" was unexpected at this time.

Использование [%1]==[-b] лучше, потому что оно не завершится с пробелами и кавычками, но не совпадет, если аргумент будет окружен кавычками.

IF [%1]==[-b] (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat "-b"

(does not match, and jumps to UNKNOWN instead of SPECIFIC)

Использование "%~1"=="-b" является наиболее надежным. %~1 удалит окружающие кавычки, если они существуют. Так что он работает с кавычками и без них, а также без аргументов.

IF "%~1"=="-b" (GOTO SPECIFIC) ELSE (GOTO UNKNOWN)

C:\> run.bat
C:\> run.bat -b
C:\> run.bat "-b"
C:\> run.bat "a b"

(all of the above tests work correctly)
5 голосов
/ 10 февраля 2011

Вы сравниваете строки. Если аргументы опущены, %1 расширяется до пустого значения, поэтому команды становятся, например, IF =="-b" GOTO SPECIFIC (что является синтаксической ошибкой). Оберните строки в кавычки (или квадратные скобки).

REM this is ok
IF [%1]==[/?] GOTO BLANK

REM I'd recommend using quotes exclusively
IF "%1"=="-b" GOTO SPECIFIC

IF NOT "%1"=="-b" GOTO UNKNOWN
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...