1

В частности, у меня проблемы с пониманием дефисов в следующих строках, взятых из викибук

if not -%1-==-- echo Argument one provided
if -%1-==-- echo Argument one not provided & exit /b

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

IF DEFINED MyVar (ECHO MyVar IS defined) ELSE (ECHO MyVar is NOT defined)

IF "%MyVar%"=="" (ECHO MyVar is NOT defined) ELSE (ECHO MyVar IS defined)

Итак, что означают (1) дефисы вокруг аргумента% 1 и (2) дефисы после знака ==?

3 ответа3

6

Учти это

C:\>if not -%1-==-- echo Argument one provided
Argument one provided

C:\>if not P%1P==PP echo Argument one provided
Argument one provided

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

Мы можем добавить пробелы, чтобы было понятно, что оператор == не изменяется окружающими символами.

C:\>if not P%1P == PP echo Argument one provided
Argument one provided

Как правило, лучше использовать обычные подходы, которые больше людей поймут быстрее (например, использование кавычек).

C:\>if not "%1"=="" echo Argument one provided
Argument one provided

С DOS и, возможно, ранними версиями Windows, я думаю, что были некоторые проблемы (которые я не помню) с использованием кавычек, которые привели к тому, что люди использовали печатные символы таким образом. Я не пробовал случай, когда% 1 содержит знак кавычки, например.

4

При использовании% 1 важно поместить что-то вокруг него, чтобы предотвратить разрыв пакетного файла, когда% 1 пуст, потому что% 1 не является переменной, он заменяется значением, как, например, SQL-инъекция , пример внедрения в пакет, и когда значение равно нулю, а% 1 находится в IF, вы получаете неработающий код. if %1=="" становится if == "" и выдает ошибку.

Что касается того, почему, если определено, не работает на% 1,% 1 является значением, а не переменной, поэтому определение там не работает. Для того, чтобы код, который работает для% 1, был пустым, вам нужен код, который не сломается, когда% 1 заменяется ничем. Попробуйте, if "%1"=="" или попробуйте, if [%1]==[]

Сказать, что% 1 выглядит немного запутанно, для меня это не выглядит хорошим соглашением! Технически это можно сделать даже в том if a%1==a%1 или if %1a==%1a но обычно используется []

Вы можете использовать кавычки, или [] или любой другой символ (ы). Но, как указал суперкат в комментарии, кавычки не являются хорошей идеей для% 1. (Поскольку, если% 1 содержит пробелы, пользователь включает кавычки в то, что передается, чтобы быть% 1, и если в% 1 и в пакетном файле есть пробел, вы помещаете кавычки вокруг% 1, кавычки будут отменены и пробел без кавычек там вызовет ошибку).

Если вы выполняли IF в командной строке и не тестировали какую-либо переменную, у вас не было бы% 1 и вам даже не понадобилось бы []. Вы скажете, IF "a b c"=="a b c" echo a или IF a==b echo a Если в пакетном файле у вас часто есть% 1, и вместо использования кавычек вокруг% 1, используйте, например, один или два символа вокруг него, например [%1] и используйте кавычки, если вам нужно сохранить пробелы, а это не% 1 эгег IF [%1]==[a] или IF [%1]==["a b"] echo a Не делать "%1" потому что% 1 может уже иметь кавычки, которые будут отменены вашими кавычками, а затем, если % 1 имеет пробел, который прерывает оператор if.

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

Переменная может иметь пробел и не содержать кавычек.

Таким образом, в этом конкретном случае командной строки, размещение кавычек около% a% не приведет к двойным кавычкам, и вы должны поместить кавычки вокруг% a%, если вы хотите проверить его на "a b".

C:\>set a=a b

C:\>echo %a%
a b

C:\>IF %a%=="a b" echo sdf
b=="a b" was unexpected at this time.

C:\>IF "%a%"=="a b" echo sdf
sdf

So ^^^ we want "%a%"

Тогда как если бы% a% содержал кавычки, это был бы другой случай

C:\>set a="a b"

C:\>echo %a%
"a b"

C:\>IF %a%=="a b" echo a
a

C:\>IF "%a%"=="a b" echo a
b""=="a b" was unexpected at this time.

C:\>

^^^^ So there we want %a% without quotes around it.

Так что все дело в том, содержит ли переменная или параметр кавычки. Если в% 1 есть пробелы, он будет содержать кавычки. Итак, мы знаем, что если бы мы сравнивали% 1 с "a b", то w не делал бы «% 1». И если бы% 1 не содержал кавычек, он не содержал бы пробелов, поэтому мы бы не делали «% 1», поэтому я думаю, что вы никогда не захотите делать «% 1». Таким образом, если% 1 содержит пробелы, в% 1 будут кавычки, и пробелы уже будут сохранены.

Я вычеркнул ниже в свете комментария суперкатера. И я добавил больше к своему посту выше.

Кавычки лучше всего использовать% 1, а не [] или какой-либо символ, такой как A или -, потому что, например, если вы используете [], то это не сохранит пробелы

C:\> if [dab] == [dab] echo sdf

в это время было неожиданно.

Скажите, if "d a b" что будет работать. Поэтому, if "%1" лучше, чем другие символы, например, if [%1] или a%1a или -%1

1

Не уверен, что вы поняли это, так что позвольте мне посмотреть, могу ли я упростить это.

Допустим, ваш командный файл получает значение %1 в командной строке, и вы хотите увидеть, является ли он "cat" или "dog". Вы можете проверить это:

if %1 == cat goto CAT
if %1 == dog goto DOG
REM Default: Complain about no dog or cat
goto OOPS
:CAT
echo I'm a cat!
REM Successful, so skip to end
goto END
:DOG
echo I'm a dog!
goto END
:OOPS
echo I didn't see a cat or dog!
REM This just falls through to the end
:END

%1 заменяется текстом cat или dog (скажем, dog), поэтому интерпретатор действительно видит это:

if dog == cat goto CAT
if dog == dog goto DOG

Но если человек, выполняющий скрипт, не включил значение в командной строке, интерпретатор увидит это:

if  == cat goto CAT
if  == dog goto DOG

Это неправильный синтаксис и приведет к ошибке. Таким образом, соглашение состоит в том, чтобы включать 1 или более символов и сначала проверять на наличие переменных, что-то вроде этого:

if %1* == * goto OOPS
REM If no value passed in, this is seen as  if * == *  which evaluates to true
if %1 == cat goto CAT
if %1 == dog goto DOG
goto END
:CAT
echo I'm a cat!
goto END
:DOG
echo I'm a dog!
goto END
:OOPS
echo You were supposed to include a type of pet!
:END

Если значение %1 равно нулю, дополнительные символы остаются для сохранения правильного синтаксиса. Я использую * , но также часто встречаются кавычки или восклицания, такие как "%1" или %1! а также дефисы, такие как --%1 или -%1- и т. д.

Человек, я не могу поверить, я все еще помню все это. :-) Надеюсь, это поможет!

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .