Как я могу проверить, определен ли аргумент при запуске / вызове командного файла?

97

Я пытаюсь использовать следующую логику проверки в пакетном файле, но блок «использования» никогда не выполняется, даже если в пакетный файл не задан параметр.

if ("%1"=="") goto usage

@echo This should not execute

@echo Done.
goto :eof

:usage
@echo Usage: %0 <EnvironmentName>
exit 1

Что я делаю не так?

Даниэль Фортунов
источник
@ double-beep - вопрос здесь (от daniel-fortunov) был задан первым, примерно за год до публикации вопроса, на который вы ссылаетесь. Какой (возможный) дубликат?
Кевин Феган,
@KevinFegan, потому что у другого вопроса больше просмотров и ответов.
двойной сигнал

Ответы:

147

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

Я также исправил синтаксическую ошибку в использовании эха, чтобы избежать знаков «больше» и «меньше». Вдобавок exitнужен /Bаргумент, иначе CMD.exeуйдет.

@echo off

if [%1]==[] goto usage
@echo This should not execute
@echo Done.
goto :eof
:usage
@echo Usage: %0 ^<EnvironmentName^>
exit /B 1
Иэн
источник
18
[% 1] == [] лучше, чем "% 1" == "", потому что он корректно обрабатывает случай, когда сам% 1 содержит двойные кавычки. "% 1" == "" выдаст сообщение «неожиданно в это время».
tekumara
2
Обратите внимание: если вы используете не аргументы командной строки, а setпеременные (я не знаю правильной терминологии пакетной обработки), вы можете захотеть использовать, "%myvar%"==""потому что, если в нем myvarесть пробелы и не указаны в кавычках, вы получите сообщение «неожиданно. "сообщение.
Пэт
1
Переменные @Pat SET можно проверить с помощью IF NOT DEFINED VarNameблока. Также +1 к тукушану за то, что не использовал кавычки в сравнении. Просто не делай этого. Никогда.
Fr0sT
10
"%~1"==""также будет работать и позаботится о случае, когда% 1 имеет двойные кавычки
Дракким
8
"%~1"==""обрабатывает пробелы в переменной, а []версия - нет.
Масло для печенья,
17

Более продвинутый пример:

⍟ неограниченные аргументы.

⍟ существуют в файловой системе (или fileили directory?) Или в общем string.

⍟ укажите, если это файл

⍟ укажите это каталог

без расширений, будет работать в устаревших скриптах!

минимальный код ☺

@echo off

: loop
      :: -------------------------- есть аргумент?
      если ["% ~ 1"] == [""] (
        эхо сделано.
        перейти к концу
      )
      :: -------------------------- аргумент существует?
      если не существует% ~ s1 (
        эхо не существует
      ) еще (
        эхо существует
        если существует% ~ s1 \ NUL (
          эхо - это каталог
        ) еще (
          эхо это файл
        )
      )
      :: --------------------------
      сдвиг
      цикл goto
      
      
:конец

Пауза

✨ прочее ..✨

■ в %~1- ~удаляет любую упаковку "или '.

■ in %~s1- sделает путь равным DOS 8.3 naming, что является хорошим трюком, позволяющим избежать пробелов в имени файла при проверке материала (и, таким образом, не нужно оборачивать ресурс дополнительными "s.

["%~1"]==[""]«не могу быть уверенным», является ли аргумент файлом / каталогом или просто стандартной строкой, поэтому вместо этого в выражении используются скобки и исходное немодифицированное %1(только без "упаковки, если таковая имеется ..)

если не было аргументов, если мы использовали, shiftи указатель на список аргументов прошел последний, выражение будет вычислено [""]==[""].

■ это настолько специфично, насколько это возможно, не прибегая к дополнительным уловкам (это будет работать даже в пакетных скриптах Windows 95 ...)

■ примеры исполнения

сохраните это как identifier.cmd

он может идентифицировать неограниченное количество аргументов (обычно вы ограничены %1- %9), просто не забудьте заключить аргументы в кавычки, или использовать именование 8.3, или перетащить их поверх (он автоматически выполняет любое из вышеперечисленных).


это позволяет запускать следующие команды:

identifier.cmd c:\windows и получить

существует
это каталог
сделано

identifier.cmd "c:\Program Files (x86)\Microsoft Office\OFFICE11\WINWORD.EXE" и получить

существует
это файл
сделано

⓷ и несколько аргументов (конечно, в этом вся суть ..)

identifier.cmd c:\windows\system32 c:\hiberfil.sys "c:\pagefile.sys" hello-world

и получить

существует
это каталог
существует
это файл
существует
это файл
не существует
сделано.

естественно, это может быть намного сложнее, но хорошие примеры всегда должны быть простыми и минимальными. :)

Надеюсь, это поможет кому-нибудь :)

опубликовано здесь: CMD Ninja - Неограниченная обработка аргументов, определение наличия в файловой системе, определение наличия файла или каталога

и вот рабочий пример, который берет любое количество файлов APK (приложений Android) и устанавливает их на ваше устройство через консоль отладки (ADB.exe): Сделайте предыдущий пост массовым установщиком APK, который не использует синтаксис ADB Install-Multi

Сообщество
источник
14

Избавьтесь от скобок.

Пример командного файла:

echo "%1"

if ("%1"=="") echo match1

if "%1"=="" echo match2

Результат выполнения вышеуказанного скрипта:

C:\>echo "" 
""

C:\>if ("" == "") echo match1 

C:\>if "" == "" echo match2 
match2

Я думаю, что на самом деле скобки являются частью строк, и они сравниваются.

Дэйв Коста
источник
1
if "%1"==""произойдет сбой, если в аргументе есть пробелы. Например: run.bat "a b". У @amr есть лучший ответ для использованияif "%~1"==""
wisbucky
6
IF "%~1"=="" GOTO :Usage

~ снимет кавычки с% 1, если указан сам% 1.

"" защитит от пропущенных специальных символов. например, вызов скрипта с помощью & ping

Амр Али
источник
1
Это лучший ответ. Другие ответы работают для некоторых случаев, но не работают для более особых случаев, таких какrun.bat "a b"
wisbucky
@wisbucky Это, похоже, не испортило принятый ответ . Что мне не хватает?
ruffin
@ruffin, Пример: run.bat ""не поймают с [%1]==[].
wisbucky 01
2
IF "%1"=="" GOTO :Continue
.....
.....
:Continue
IF "%1"=="" echo No Parameter given
Говард Ротенбург
источник
Это вылетает дляrun.bat "a b"
wisbucky
2

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

@echo off
:: add other test for the arguments here...
if not [%1]==[] goto main
:: --------------------------
echo This command does something.
echo.
echo %0 param%%1 param%%2
echo       param%%1 the file to operate on
echo       param%%1 another file

:: --------------------------
exit /B 1

:main
:: --------------------------
echo do something with all arguments (%%* == %*) here...

Однако, если вам не нужно использовать cmd / batch, используйте bash в WSL или PowerShell, они имеют более разумный синтаксис и меньше загадочных функций.

мастерxilo
источник
0

ЕСЛИ "% 1" == "" завершится ошибкой, все версии этого не будут выполнены при определенных условиях ядовитого символа. Только IF DEFINED или IF NOT DEFINED безопасны

коди
источник
if [not] defined ...не работает с такими параметрами, как %1. У вас есть пример, где if "%~1" ...не работает?
Стефан