На Java так легко создать программу командной строки!
На Java так легко создать программу командной строки!

Всем привет, я Юпи. Для студентов, не знающих фронтенд, я занимаюсь разработкой. Инструменты командной строки Это хороший способ продемонстрировать возможности системы. существовать Java Разработано в Инструментах командной строки также очень просты, с помощью фреймворка Use вы можете изучить их за несколько минут~

Начало работы с Пикокли

Picocli да Java Среди них лично я считаю наиболее полной и простой командную. Фреймворк разработки строк может помочь каждому быстро разработать Инструменты командной строки。

Связанные с Интернетом Учебников по фреймворку Picocli очень мало.,Самый рекомендуемый способ использования начала — посмотреть урок по рыбьей коже.,Просто прочитайте официальную документацию.

Официальная документация: https://picocli.info/

Рекомендуется начать с официального краткого руководства: https://picocli.info/quick-guide.html.

В общем, шаги для изучения новых технологий следующие: сначала пробежаться Демо-версия «Начало работы», а затем изучить технические характеристики технологии.

Демо-версия «Начало работы»

1) в Maven проект pom.xml представлено в файле picocli Зависимости:

Язык кода:javascript
копировать
<!-- https://picocli.info -->
<dependency>
    <groupId>info.picocli</groupId>
    <artifactId>picocli</artifactId>
    <version>4.7.5</version>
</dependency>

Тогда мы com.yupi Создать новый пакет cli.example пакет для хранения всего и Начало работы с Пример кода, связанного с Пикокли.

2) Скопируйте пример кода из официального руководства по быстрому запуску в com.yupi.cli.example Упакованный и слегка модифицированный run Код метода печатает значение параметра.

Полный код выглядит следующим образом:

Язык кода:javascript
копировать
package com.yupi.cli.example;

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(name = "ASCIIArt", version = "ASCIIArt 1.0", mixinStandardHelpOptions = true) 
public class ASCIIArt implements Runnable { 

    @Option(names = { "-s", "--font-size" }, description = "Font size") 
    int fontSize = 19;

    @Parameters(paramLabel = "<word>", defaultValue = "Hello, picocli", 
               description = "Words to be translated into ASCII art.")
    private String[] words = { "Hello,", "picocli" }; 

    @Override
    public void run() {
        // Реализуйте бизнес-логику самостоятельно
        System.out.println("fontSize = " + fontSize);
        System.out.println("words = " + String.join(",", words));
    }

    public static void main(String[] args) {
        int exitCode = new CommandLine(new ASCIIArt()).execute(args); 
        System.exit(exitCode); 
    }
}

Не беда, если вы не понимаете этот код. В официальной документации дано очень подробное объяснение:

Пожалуйста, переведите это для всех:

  1. Создать реализацию Runnable или Callable класс интерфейса, это просто команда.
  2. использовать @Command аннотация отметить класс и дать ему имя,mixinStandardHelpOptions свойствоустановлен на true Может быть автоматически добавлен в приложение. --help и --version параметры.
  3. проходить @Option аннотациябудет выставленоустановлен накомандная строка, вы можете установить имя и описание для параметра.
  4. проходить @Parameters аннотациябудет выставленоустановлен накомандная Параметр строки, вы можете указать значение по умолчанию, описание и другую информацию.
  5. Picocli преобразует параметр командной строки в строго типизированное значение и автоматически вставляет его в поле аннотации.
  6. в классе run или call Бизнес-логика определена в методе и вызывается при успешном анализе команды (пользователь нажимает Enter).
  7. существовать main в методе,проходить CommandLine Объект execute метод для обработки команд, введенных пользователем, а остальное остается на усмотрение Picocli Фреймворк для анализа команд и выполнения бизнес-логики~
  8. CommandLine.execute Метод возвращает код выхода. Можно позвонить System.exit И используйте код выхода в качестве параметра, чтобы указать успех или неудачу вызывающего процесса.

3) Давайте изменим параметры выполнения (args) основной программы, чтобы протестировать программу и успешно увидеть выходные результаты.

Проведя эту Демо-версию «Начало работы», мы можем просто подвести итог процесса разработки команды:

  1. Создать команду
  2. Установить опции и параметры
  3. Написание бизнес-логики для выполнения команд.
  4. проходить CommandLine Объект принимает ввод и выполняет команды

существовать Прошел Демо-версия «Начало работы» Наконец, давайте узнаем кое-что Picocli развиватькомандная строкаиз Практичные функции。

Практичные функции

1. Справочное руководство

Добавив в класс @Command Параметры аннотации mixinStandardHelpOptions установлен на true Чтобы включить:

Язык кода:javascript
копировать
@Command(name = "ASCIIArt", mixinStandardHelpOptions = true) 

Затем измените входной параметр, установленный в основной программе. на --help Вы можете распечатать справочное руководство по команде, как показано ниже:

Как видите, справочное руководство, созданное Picocli, не только стандартизировано, но также ясно и полно.

2. Анализ команд

Пикокли Ядро анализ возможностей команды,Возможность анализировать параметры и параметры полной команды.,И заполните его атрибутом Объект.

Picocli использует аннотации для реализации синтаксического анализа команд. Нет необходимости писать код самостоятельно, и весь класс выглядит очень понятно.

Ядро 2 индивидуальныйаннотацияна самом делесуществовать Демо-версия «Начало работы» Мы уже использовали:

  • @Option аннотацияиспользовать для вариантов разбора
  • @Parameters аннотацияиспользоватьдля анализа параметров

Пример кода выглядит следующим образом:

Язык кода:javascript
копировать
@Option(names = { "-s", "--font-size" }, description = "Font size") 
int fontSize = 19;

@Parameters(paramLabel = "<word>", defaultValue = "Hello, picocli", 
           description = "Words to be translated into ASCII art.")
private String[] words = { "Hello,", "picocli" }; 

Для этих аннотаций можно указать параметры. Наиболее часто используемые параметры:

1) Параметр имен аннотации @Option: указывает английское название параметра.

2) параметр описания: укажите информацию описания, чтобы сделать сгенерированное справочное руководство и подсказки более понятными.

3) Параметр paramLabel аннотации @Parameters: метка параметра, которая действует как информация описания.

4) Параметр defaultValue аннотации @Parameters: значение по умолчанию, см. документ: https://picocli.info/#_default_values

5) обязательные параметры: обязательны, справочный документ: https://picocli.info/#_required_arguments

Пример кода выглядит следующим образом:

Язык кода:javascript
копировать
class RequiredOption {
    
    @Option(names = "-a", required = true)
    String author;
}

Кроме того, синтаксический анализ команд естественным образом поддерживает многозначные опционы,Просто измените тип атрибута объекта, установленный на тип массива.,например:

Язык кода:javascript
копировать
@Option(names = "-option")
int[] values;

Подробную информацию можно найти на странице Официальная. документация: https://picocli.info/#_multiple_values

Для получения дополнительной информации об использовании параметров и аннотаций параметров вы также можете прочитать официальную документацию: https://picocli.info/quick-guide.html#_options_and_parameters.

3. Интерактивный ввод

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

Как показано ниже:

Picocli обеспечивает хорошую поддержку интерактивного ввода. Я разобрал около 4 режимов интерактивного ввода.

1) Базовые способности

Типичный сценарий применения интерактивного ввода: когда пользователь хочет войти в систему, ему предлагается ввести «Введите свой пароль».

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

ссылка Официальная документация: https://picocli.info/#_interactive_password_options

Язык кода:javascript
копировать
package com.yupi.cli.example;

import picocli.CommandLine;
import picocli.CommandLine.Option;

import java.util.concurrent.Callable;

public class Login implements Callable<Integer> {
    @Option(names = {"-u", "--user"}, description = "User name")
    String user;

    @Option(names = {"-p", "--password"}, description = "Passphrase", interactive = true)
    String password;

    public Integer call() throws Exception {
        System.out.println("password = " + password);
        return 0;
    }

    public static void main(String[] args) {
        new CommandLine(new Login()).execute("-u", "user123", "-p");
    }
}

Давайте проанализируем приведенный выше код, который в основном состоит из 4 частей:

1) Сначала необходимо реализовать класс команды Callable интерфейс

Язык кода:javascript
копировать
public class Login implements Callable<Integer> {
 ...
}

2) будет @Option аннотированный interactive параметрустановлен на true, что указывает на то, что эта опция поддерживает интерактивный ввод

Язык кода:javascript
копировать
@Option(names = {"-p", "--password"}, interactive = true)
String password;

3) После ввода всех параметров он будет выполнен. call Метод, в котором может быть написана конкретная бизнес-логика:

Язык кода:javascript
копировать
public Integer call() throws Exception {
    System.out.println("password = " + password);
    return 0;
}

4) Выполните команду в методе Main и передайте параметры:

Язык кода:javascript
копировать
new CommandLine(new Login()).execute("-u", "user123", "-p");

Выполним приведенный выше код и увидим, что программа предлагает нам ввести пароль:

Обратите внимание, что если jar При запуске указанной выше программы в пакетном режиме при вводе пользователем значения по умолчанию консоль существования не отображается (аналогично тому, как это происходит при вводе пароля). от Picocli 4.6 начало версии, которое можно указать с помощью @Option аннотированный echo Параметры true для отображения пользовательского ввода и передачи prompt Параметр определяет подсказку, которая помогает пользователю войти.

2) Несколько интерактивных опций

Picocli поддерживает указание нескольких параметров интерактивного ввода в одной команде, последовательно запрашивая пользователя и получая ввод.

Добавьте еще один параметр checkPassword в приведенный выше код, а также включите интерактивный ввод. Код выглядит следующим образом:

Язык кода:javascript
копировать
public class Login implements Callable<Integer> {
    @Option(names = {"-u", "--user"}, description = "User name")
    String user;

    @Option(names = {"-p", "--password"}, description = "Passphrase", interactive = true)
    String password;

    @Option(names = {"-cp", "--checkPassword"}, description = "Check Password", interactive = true)
    String checkPassword;

    public Integer call() throws Exception {
        System.out.println("password = " + password);
        System.out.println("checkPassword = " + checkPassword);
        return 0;
    }

    public static void main(String[] args) {
        new CommandLine(new Login()).execute("-u", "user123", "-p");
    }
}

Но когда мы запустим приведенный выше код, мы обнаружим, почему мне было предложено только ввести пароль, а не подтвердить пароль?

Это связано с Picocli Согласно правилам платформы, пользователь должен указать в команде параметры, требующие интерактивного ввода (например, -p),Только тогда пользователю будет предложено ввести данные.

Поэтому нам нужно изменить приведенный выше код main Метод, дополняющий ввод команды -cp параметр:

Язык кода:javascript
копировать
public static void main(String[] args) {
    new CommandLine(new Login()).execute("-u", "user123", "-p", "-cp");
}

Выполните его еще раз. На этот раз программа напомнит нам ввести два варианта:

В зависимости от фактического использования интерактивный ввод можно разделить на 2 режима:

  • Необязательный интерактивный:пользователь может напрямую вводить параметры во всей строке команд.,Вместо предоставления оперативной информации для использования пользователями.
  • Принудительный интерактивный режим: пользователю необходимо ввести запрос и ввести параметр, пропуски не допускаются.

Эти два режима описаны ниже.

3) Дополнительный интерактивный

По умолчанию,да нельзя напрямую указать какие-либо параметры для интерактивной опции в команде существования,Только интерактивный ввод,Например, команда содержит -p xxx Будет сообщено об ошибке.

Дополнительный интерактивный Официальная документация: https://picocli.info/#_optionally_interactive

Давайте проверим это, введя следующий параметр в приведенный выше пример кода:

Язык кода:javascript
копировать
new CommandLine(new Login()).execute("-u", "user123", "-p", "xxx", "-cp");

Результат выполнения такой, как показано ниже, и появляется сообщение об ошибке о несоответствии параметров:

Официальный представитель предоставляет дополнительное интерактивное решение, настраивая @Option аннотированный arity Атрибуты, определяющие количество параметров, которые может принять каждый параметр, могут решить эту проблему.

Официальное представление arity: https://picocli.info/#_arity

Пример кода выглядит следующим образом:

Язык кода:javascript
копировать
@Option(names = {"-p", "--password"}, arity = "0..1", description = "Passphrase", interactive = true)
String password;

Затем вы можете установить значения интерактивных параметров непосредственно в полной команде:

Язык кода:javascript
копировать
new CommandLine(new Login()).execute("-u", "user123", "-p", "123", "-cp");

Результат выполнения такой, как показано на рисунке, и пользователю больше не запрашивается ввод данных. password Параметры,ида直接读取了命令中из值:

Здесь Юпи рекомендует лучше всего упражняться: Рекомендуется добавлять все опции, требующие интерактивного ввода. arity Параметры (Общие да arity = "0..1"),Таким образом, пользователи могут напрямую заполнять параметры опций в полной команде.,Интерактивный ввод также является опцией.

Пример кода выглядит следующим образом:

Язык кода:javascript
копировать
public class Login implements Callable<Integer> {
    @Option(names = {"-u", "--user"}, description = "User name")
    String user;

    // набор arity Параметры, опционально интерактивные
    @Option(names = {"-p", "--password"}, arity = "0..1", description = "Passphrase", interactive = true)
    String password;

    // набор arity Параметры, опционально интерактивные
    @Option(names = {"-cp", "--checkPassword"}, arity = "0..1", description = "Check Password", interactive = true)
    String checkPassword;

    public Integer call() throws Exception {
        System.out.println("password = " + password);
        System.out.println("checkPassword = " + checkPassword);
        return 0;
    }

    public static void main(String[] args) {
        new CommandLine(new Login()).execute("-u", "user123", "-p", "123", "-cp", "456");
    }
}
4) Силовое взаимодействие

Как упоминалось ранее, если пользователь не вводит интерактивные параметры в команду (например, -p),Тогда система не будет предлагать пользователю ввести эту опцию.,Значение свойства будет значением по умолчанию (например, null).

Например, следующая команда не включает -p Параметры:

Язык кода:javascript
копировать
new CommandLine(new Login()).execute("-u", "user123");

При запуске вы обнаружите, что программа не запрашивает у пользователя ввод данных. -p Параметр опции, и да напрямую выводит результат, значение равно null

Но иногда мы требуем от пользователей ввести определенный параметр вместо использования пустого значения по умолчанию. Что нам делать?

Официальное решение — принудительно использовать интерактивность, см. документ: https://picocli.info/#_forcing_interactive_input.

Да,Официальное решение требует от вас определения собственной бизнес-логики. Принцип: Атрибуты оцениваются после выполнения команды дасуществовать.,Если пользователь не вводит указанные параметры,Потом сновапроходить System.console().readLine и другие методы предлагают пользователю ввести пример. кода выглядит следующим образом:

Язык кода:javascript
копировать
@Command
public class Main implements Runnable {
    @Option(names = "--interactive", interactive = true)
    String value;

    public void run() {
        if (value == null && System.console() != null) {
            // Активно запрашивать ввод данных пользователем
            value = System.console().readLine("Enter value for --interactive: ");
        }
        System.out.println("You provided value '" + value + "'");
    }

    public static void main(String[] args) {
        new CommandLine(new Main()).execute(args);
    }
}

Лично мне это решение не очень нравится,Потому что нам нужно написать дополнительный код подсказки,Чувство возвращается к автономной реализации.

План, который придумал Юпи,Напишите общую программу проверки,Если команда ввода пользователя не включает интерактивную опцию,Затем вы можете автоматически добавить эту опцию во входную команду.,Это приводит к запуску интерактивного ввода.

Более того, аргументы args указывают, существует ли соответствующий вариант существования в массиве. Если существование не существует, добавьте элементы параметра в массив.

Как небольшая точка расширения, эта идея не сложна в реализации и может быть реализована самостоятельно. (Советы: вы можете использовать отражение для автоматического чтения названий необходимых опций)

4, инструкция для детей

Подкоманда да означает, что команда содержит группу команд,Эквивалент групповой вложенности команд.,Подходит для командных строковых программ с большим количеством функций и более сложными функциями.,например git、docker Заказы и т. д.

Официальная документация: https://picocli.info/#_subcommands

В Picocli существует два способа задания подкоманд.

1) Декларативный

проходить @Command аннотированный subcommands Свойства для добавления подкоманд к команде, преимущество более интуитивное и понятное.

Пример кода выглядит следующим образом:

Язык кода:javascript
копировать
@Command(subcommands = {
    GitStatus.class,
    GitCommit.class,
    GitAdd.class,
    GitBranch.class,
    GitCheckout.class,
    GitClone.class,
    GitDiff.class,
    GitMerge.class,
    GitPush.class,
    GitRebase.class,
    GitTag.class
})
public class Git { /* ... */ }
2) Программатик

Создание CommandLine объект, позвоните addSubcommand метод привязки подкоманд, преимущество которого заключается в большей гибкости.

Пример кода выглядит следующим образом:

Язык кода:javascript
копировать
CommandLine commandLine = new CommandLine(new Git())
        .addSubcommand("status",   new GitStatus())
        .addSubcommand("commit",   new GitCommit())
        .addSubcommand("add",      new GitAdd())
        .addSubcommand("branch",   new GitBranch())
        .addSubcommand("checkout", new GitCheckout())
        .addSubcommand("clone",    new GitClone())
        .addSubcommand("diff",     new GitDiff())
        .addSubcommand("merge",    new GitMerge())
        .addSubcommand("push",     new GitPush())
        .addSubcommand("rebase",   new GitRebase())
        .addSubcommand("tag",      new GitTag());
упражняться

Давайте напишем пример программы, которая поддерживает добавление, удаление и запрос трех подкоманд, а также передачу различных аргументов для проверки эффекта.

Полный код выглядит следующим образом:

Язык кода:javascript
копировать
package com.yupi.cli.example;

import picocli.CommandLine;
import picocli.CommandLine.Command;

@Command(name = "main", mixinStandardHelpOptions = true)
public class SubCommandExample implements Runnable {

    @Override
    public void run() {
        System.out.println("Выполнить основную команду");
    }

    @Command(name = "add", description = "Увеличивать", mixinStandardHelpOptions = true)
    static class AddCommand implements Runnable {
        public void run() {
            System.out.println("Выполнить команду добавления");
        }
    }

    @Command(name = "delete", description = "удалить", mixinStandardHelpOptions = true)
    static class DeleteCommand implements Runnable {
        public void run() {
            System.out.println("Выполнить команду удаления");
        }
    }

    @Command(name = "query", description = "запрос", mixinStandardHelpOptions = true)
    static class QueryCommand implements Runnable {
        public void run() {
            System.out.println("Выполнить команду запроса");
        }
    }

    public static void main(String[] args) {
        // Выполнить основную команду
        String[] myArgs = new String[] { };
        // Просмотрите справочное руководство по основной команде
//        String[] myArgs = new String[] { "--help" };
        // Выполнить команду добавления
//        String[] myArgs = new String[] { "add" };
        // Выполнить команду добавленияиз帮助手册
//        String[] myArgs = new String[] { "add", "--help" };
        // Если вы выполните команду, которая не содержит существования, будет сообщено об ошибке.
//        String[] myArgs = new String[] { "update" };
        int exitCode = new CommandLine(new SubCommandExample())
                .addSubcommand(new AddCommand())
                .addSubcommand(new DeleteCommand())
                .addSubcommand(new QueryCommand())
                .execute(myArgs);
        System.exit(exitCode);
    }
}

Тест был запущен и обнаружил, что при вводе --help параметры, основная команда и вся информация о подкомандах распечатываются, доказывая, что подкоманды успешно связаны.

упражняться

Проект создания индивидуального кода Programming Navigation Planet предназначен для использования Picocli для разработки приложений командной строки.

👉🏻 Серия руководств по оригинальному проекту по программированию навигации: https://yuyuanweb.feishu.cn/wiki/SePYwTc9tipQiCktw7Uc7kujnCd

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose