Як я можу перевірити, чи визначено аргумент під час запуску / виклику командного файлу?


96

Я намагаюся використовувати наступну логіку перевірки у пакетному файлі, але блок "використання" ніколи не виконується, навіть якщо в командний файл не вводиться жоден параметр.

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

@echo This should not execute

@echo Done.
goto :eof

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

Що я роблю неправильно?


Відповіді:


146

Перевірка, чи встановлено аргумент командного рядка, може бути [%1]==[], але, як зазначає Дейв Коста , це також спрацює."%1"==""

Я також виправив синтаксичну помилку в ехо використання, щоб уникнути знаків більше і менше. Окрім того, аргумент " exitПотреби" вимагає припинення./BCMD.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" == "" матиме помилку із повідомленням "несподівано в цей час".
текумара

2
Зауважте, що якщо ви використовуєте не аргументи командного рядка, а setзмінні (я не знаю правильної пакетної термінології), можливо, ви захочете використовувати, "%myvar%"==""тому що якщо myvarв ньому є пробіли і не вказано, у цей час ви отримаєте "несподіваний " повідомлення.
Пет

1
Змінні @Pat SET можна перевірити IF NOT DEFINED VarNameблоком. Також +1 тукушану за невикористання цитат у порівнянні. Просто не робіть цього. Ніколи.
Пт0sT

10
"%~1"==""також буде працювати і піклуватися про випадок, коли% 1 має подвійні лапки
Драккім

8
"%~1"==""обробляє пробіли у змінній, тоді як []версія цього не робить.
Cookie Butter

17

Більш просунутий приклад:

Необмежена кількість аргументів.

⍟ існують у файловій системі ( fileабо directory?), Або загальній string.

⍟ вкажіть, чи є файл

⍟ вказати - це каталог

Чи не ⍟ немає розширення, буде працювати в старих скриптах!

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

@echo вимкнено

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

пауза

✨ інші речі..✨

■ в %~1- ~видаляє будь-яке обгортання "або '.

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

["%~1"]==[""]"не можу бути впевненим", якщо аргументом є файл / каталог або просто загальний рядок, тому замість цього вираз використовує дужки та оригінал немодифікований %1(лише без "обтікання, якщо такий є).

якщо не було аргументів, якщо ми використовували, shiftа покажчик arg-list передав останній, вираз буде обчислено [""]==[""].

■ це настільки конкретно, наскільки ви можете бути, не використовуючи більше хитрощів (це буде працювати навіть у пакетних сценаріях 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 Це, здається, не заплутує прийняту відповідь . Що я пропускаю?
jorffin

@ruffin, Приклад: run.bat ""не буде спійманий за допомогою [%1]==[].
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, вони мають більш розумний синтаксис і менше загадкових особливостей.


0

ЯКЩО "% 1" == "" не вдасться, всі версії цього зазнають невдачі за певних умов характеру отрути. Безпечними є лише ТЕМИ, ЩО ВИЗНАЧЕНО або ЯКЩО НЕ ВКАЗАНО


if [not] defined ...не працює з такими параметрами, як %1. У вас є приклад, де if "%~1" ...не працює?
Stephan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.