Використання параметрів у пакетних файлах у командному рядку Windows


161

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

Наприклад, скажімо, у мене є програма з назвою hello.bat. Коли я входжу hello -aв командному рядку Windows, як я можу повідомити програмі про те, що -aбуло передано як аргумент?


Як передати параметри командного рядка до пакетного файлу: stackoverflow.com/questions/26551/…
Eric Leschinski

3
Він згадує "командний рядок DOS".
David R Tribble

Відповіді:


287

Як уже говорили інші, до параметрів, що проходять через командний рядок, можна отримати доступ у пакетних файлах із позначенням %1до %9. Також є два інших жетони, якими ви можете користуватися:

  • %0- ім'я виконуваного файлу (пакетного файлу), визначене в командному рядку .
  • %*- це всі параметри, вказані в командному рядку - це дуже корисно, якщо ви хочете переслати параметри до іншої програми.

Існує також безліч важливих прийомів, яких слід знати, крім простого доступу до параметрів.

Перевірка, чи був переданий параметр

Це робиться з такими конструкціями, як IF "%~1"==""це правда, якщо і лише тоді, коли аргументи взагалі не були передані. Зверніть увагу на символ тильди, який спричиняє видалення будь-яких навколишніх лапок зі значення %1; без тильду ви отримаєте несподівані результати, якщо це значення включає подвійні лапки, включаючи можливість синтаксичних помилок.

Поводження з більш ніж 9 аргументами (або просто полегшення життя)

Якщо вам потрібно отримати доступ до більше ніж 9 аргументів, ви повинні використовувати команду SHIFT. Ця команда зміщує значення всіх аргументів на одне місце, так що%0 приймає значення %1, %1приймає значення %2і т.д. %9приймає значення десятого аргументу (якщо такий присутній), яке не було доступним через жодну змінну перед викликомSHIFT (введіть команда SHIFT /?для додаткових опцій).

SHIFTтакож корисний, коли ви хочете легко обробити параметри, не вимагаючи, щоб вони були представлені у певному порядку. Наприклад, сценарій може розпізнавати прапори -aі -bв будь-якому порядку. Хороший спосіб розбору командного рядка в таких випадках є

:parse
IF "%~1"=="" GOTO endparse
IF "%~1"=="-a" REM do something
IF "%~1"=="-b" REM do something else
SHIFT
GOTO parse
:endparse
REM ready for action!

Ця схема дозволяє проаналізувати досить складні командні рядки, не божевільно.

Заміна параметрів партії

Для параметрів, що представляють імена файлів, оболонка забезпечує безліч функціональних можливостей, пов’язаних з роботою з файлами, недоступними іншим способом. Доступ до цієї функціональності можна отримати з конструкцій, які починаються з%~ .

Наприклад, щоб отримати розмір файлу, переданого як аргумент, використовуйте

ECHO %~z1

Щоб отримати шлях до каталогу, з якого був запущений пакетний файл (дуже корисно!), Який ви можете використовувати

ECHO %~dp0

Ви можете переглянути весь спектр цих можливостей, ввівши CALL /?командний рядок.


4
Конструкція: parse,: endparse - краса, навіть із GOTO. Дякую! (Я маю на увазі, DOS-BASIC змушений GOTO)
mmrtnt

1
Ця методика може вийти з ладу під час виклику BAT з powerhell. Цитований аргумент на зразок "name=John"стане name Johnпід час exe. Обхідний шлях полягає в оточенні одинарних лапок,'"name=John"'
cmcginty

1
Як я пройшов так довго без CALL /?!? Тут я весь час стикався з Google.
bigtlb

@Jon Я написав bat-файл, який містить лише один код echo% 1, якщо я викликаю його через cmd, наприклад xx.bat & параметр> "C: \ yy.txt", викликаючи файл bat з параметром і записуючи у файл txt, але якщо я даю & в параметрі на початку або в кінці він не працює. Будь-який інший текст працює добре.
Алекс Матвій

56

Використання параметрів у пакетних файлах:% 0 та% 9

Пакетні файли можуть посилатися на слова, передані як параметри з лексемами: %0до %9.

%0 is the program name as it was called.
%1 is the first command line parameter
%2 is the second command line parameter
and so on till %9.

Параметри, передані в командному рядку, повинні бути буквено-цифровими символами та обмежені пробілами. Оскільки %0назва програми, як її називали, в DOS%0 буде порожньо для AUTOEXEC.BAT, якщо її запустити під час завантаження.

Приклад:

Помістіть таку команду в пакетний файл під назвою mybatch.bat:

@echo off
@echo hello %1 %2
pause

Викликає такий пакетний файл: mybatch john billyвиводиться:

hello john billy

Отримайте більше 9 параметрів для пакетного файлу, використовуйте:% *

Маркер Percent Star %*означає "решта параметрів". Ви можете використовувати цикл для захоплення їх, як визначено тут:

http://www.robvanderwoude.com/parameters.php

Примітки про роздільники параметрів партії

Деякі символи в параметрах командного рядка ігноруються пакетними файлами, залежно від версії DOS, незалежно від того, вони "уникнуті" чи ні, і часто залежно від їх розташування в командному рядку:

commas (",") are replaced by spaces, unless they are part of a string in 
double quotes

semicolons (";") are replaced by spaces, unless they are part of a string in 
double quotes

"=" characters are sometimes replaced by spaces, not if they are part of a 
string in double quotes

the first forward slash ("/") is replaced by a space only if it immediately 
follows the command, without a leading space

multiple spaces are replaced by a single space, unless they are part of a 
string in double quotes

tabs are replaced by a single space

leading spaces before the first command line argument are ignored

5

Пакетні файли автоматично передають текст після програми до тих пір, поки вони є змінними для їх призначення. Вони передаються для того, щоб їх відправити; наприклад,% 1 буде першим рядком, надісланим після виклику програми тощо.

Якщо у вас є Hello.bat і вміст:

@echo off
echo.Hello, %1 thanks for running this batch file (%2)
pause

і ви викликаєте пакет у команді via

hello.bat APerson241% дата%

ви отримаєте це повідомлення назад:

Привіт, APerson241 дякую за запуск цього пакетного файлу (01.11.2013)


4

@ Йона :parse/:endparse схеми є відмінним початком, і він має свою подяку за початковий прохід, але якщо ви думаєте , що болісна партія система Windows , дозволить вам легко вимкнути , що ... ну, мій друг, ти в шок. Я провів цілий день з цим дияволом, і після довгих болісних досліджень і експериментів я нарешті зумів щось життєздатне для корисної програми.

Скажемо, що ми хочемо реалізувати утиліту foobar. Це вимагає початкової команди. Він має необов'язковий параметр, --fooякий приймає необов'язкове значення (що, звичайно, не може бути іншим параметром); якщо значення відсутнє, воно за замовчуванням default. Він також має необов'язковий параметр, --barякий приймає необхідне значення. Нарешті, він може взяти прапор --bazбез значення дозволеного. О, і ці параметри можуть прийти в будь-якому порядку.

Іншими словами, це виглядає приблизно так:

foobar <command> [--foo [<fooval>]] [--bar <barval>] [--baz]

Складні? Ні, це здається досить типовим для реальних комунальних послуг. ( gitхто?)

Без зайвих прихильностей, ось рішення:

@ECHO OFF
SETLOCAL
REM FooBar parameter demo
REM By Garret Wilson

SET CMD=%~1

IF "%CMD%" == "" (
  GOTO usage
)
SET FOO=
SET DEFAULT_FOO=default
SET BAR=
SET BAZ=

SHIFT
:args
SET PARAM=%~1
SET ARG=%~2
IF "%PARAM%" == "--foo" (
  SHIFT
  IF NOT "%ARG%" == "" (
    IF NOT "%ARG:~0,2%" == "--" (
      SET FOO=%ARG%
      SHIFT
    ) ELSE (
      SET FOO=%DEFAULT_FOO%
    )
  ) ELSE (
    SET FOO=%DEFAULT_FOO%
  )
) ELSE IF "%PARAM%" == "--bar" (
  SHIFT
  IF NOT "%ARG%" == "" (
    SET BAR=%ARG%
    SHIFT
  ) ELSE (
    ECHO Missing bar value. 1>&2
    ECHO:
    GOTO usage
  )
) ELSE IF "%PARAM%" == "--baz" (
  SHIFT
  SET BAZ=true
) ELSE IF "%PARAM%" == "" (
  GOTO endargs
) ELSE (
  ECHO Unrecognized option %1. 1>&2
  ECHO:
  GOTO usage
)
GOTO args
:endargs

ECHO Command: %CMD%
IF NOT "%FOO%" == "" (
  ECHO Foo: %FOO%
)
IF NOT "%BAR%" == "" (
  ECHO Bar: %BAR%
)
IF "%BAZ%" == "true" (
  ECHO Baz
)

REM TODO do something with FOO, BAR, and/or BAZ
GOTO :eof

:usage
ECHO FooBar
ECHO Usage: foobar ^<command^> [--foo [^<fooval^>]] [--bar ^<barval^>] [--baz]
EXIT /B 1

Так, це насправді так погано. Дивіться мою подібну публікацію на веб- сайті https://stackoverflow.com/a/50653047/421049 , де я надаю додатковий аналіз того, що відбувається в логіці, і чому я використовував певні конструкції.

Прихований. Більшу частину цього мені довелося сьогодні вивчити. І це боляче.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.