Понимание работы с аргументами и опциями консоли

Дата обновления перевода 2023-08-21

Понимание работы с аргументами и опциями консоли

Приложения Symfony Console следуют тому же стандарту docopt, который используется в большинстве утилит CLI. Эта статья объявняет, как работать с пограничными случаями, когда команды определяют опции с требуемыми значениями, без значений и т.д. Прочтите другую статью, чтобы узнать об использовании аргументов и опций внутри команд Symfony Console.

Посмотрите не следующую команду, которая имеет три опции:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
namespace Acme\Console\Command;

use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(name: 'demo:args', description: 'Describe args behaviors')]
class DemoArgsCommand extends Command
{
    protected function configure(): void
    {
        $this
            ->setDefinition(
                new InputDefinition([
                    new InputOption('foo', 'f'),
                    new InputOption('bar', 'b', InputOption::VALUE_REQUIRED),
                    new InputOption('cat', 'c', InputOption::VALUE_OPTIONAL),
                ])
            );
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        // ...
    }
}

Так как опция foo не принимает значение, она будет либо false (если она не передана команде), либо true (если пользователь передал --foo). Значение опции bar (и соответственно её ярлыка b) является обязательным. Оно может быть отделено от имени опции либо пробелами, либо символами =. Опция cat (и её ярлык c) ведёт себя также, кроме того, что она не требует значения. Изучите следующую таблицу, чтобы получить представление о возможных способах передачи опций:

???? foo bar cat
--bar=Hello false "Hello" null
--bar Hello false "Hello" null
-b=Hello false "=Hello" null
-b Hello false "Hello" null
-bHello false "Hello" null
-fcWorld -b Hello true "Hello" "World"
-cfWorld -b Hello false "Hello" "fWorld"
-cbWorld false null "bWorld"

Всё становится немного сложнее, когда команда также принимает необязательный аргумент:

1
2
3
4
5
6
// ...

new InputDefinition([
    // ...
    new InputArgument('arg', InputArgument::OPTIONAL),
]);

Вам может понадобиться использовать специальный разделитель --, чтобы отделить опции от аргументов. Посмотрите на пятый пример в таблице ниже, где он используется для того, чтобы сообщеить команде, что World является значением для arg, а не значением необязательной опции cat:

???? bar cat arg
--bar Hello "Hello" null null
--bar Hello World "Hello" null "World"
--bar "Hello World" "Hello World" null null
--bar Hello --cat World "Hello" "World" null
--bar Hello --cat -- World "Hello" null "World"
-b Hello -c World "Hello" "World" null