Использование параметров в командных файлах в командной строке Windows

161

В Windows, как вы получаете доступ к аргументам, передаваемым при запуске командного файла?

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

Персона
источник
Как передать параметры командной строки в командный файл: stackoverflow.com/questions/26551/…
Эрик Лещинский,
3
Он упоминает «Командная строка DOS».
Дэвид Р. Триббл

Ответы:

287

Как и другие уже говорил, параметры , передаваемые через командную строку можно получить в пакетных файлах с пометкой %1в %9. Есть также два других токена, которые вы можете использовать:

  • %0это исполняемый файл (пакетный файл) имя , как указано в командной строке .
  • %*это все параметры, указанные в командной строке - это очень полезно, если вы хотите переслать параметры в другую программу.

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

Проверка, был ли передан параметр

Это делается с помощью конструкций like 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 из powershell. Цитируемый аргумент вроде "name=John"станет name Johnво время exe. Обходной путь должен '"name=John"'
заключаться в
1
Как я так долго обходился без CALL /?? Здесь я все время сталкиваюсь с Google.
bigtlb
@Jon Я написал bat-файл, который содержит только один код echo% 1, если я вызываю его через cmd, например, xx.bat & parameter> "C: \ yy.txt", вызываю bat-файл с параметром и записываю в txt-файл, но если я даю & в параметре в начале или конце это не работает. Любой другой текст работает нормально.
Алекс Мэтью
56

Использование параметров в пакетных файлах:% 0 и% 9

Пакетные файлы могут ссылаться на слова, передаваемые в качестве параметров с токенами: %0to %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 %*означает «остальные параметры». Вы можете использовать цикл for, чтобы получить их, как определено здесь:

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

и вы вызываете пакет в команде через

hello.bat APerson241% date%

Вы должны получить это сообщение обратно:

Здравствуйте, APerson241, спасибо за запуск этого командного файла (01/11/2013)

rud3y
источник
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 , где я предоставляю более подробный анализ того, что происходит в логике, и почему я использовал определенные конструкции.

Уродство. Большую часть этого я должен был выучить сегодня. И это больно.

Гаррет Уилсон
источник
3

Использовать переменные т.е. .BATпеременные и называются %0в%9

tohava
источник