Перейти к пакету флагов синтаксического анализа командной строки, чтобы быстро приступить к работе

Go

Эта статья представляет собой краткий обзор пакета флагов стандартной библиотеки Go.

Обзор

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

Конечно, также есть много сторонних библиотек в дополнение к стандартной библиотечной флага. Например, чтобы заменить флагpflag, который поддерживает синтаксический анализ командной строки в стиле POSIX. Что касается стиля POSIX, в конце этой статьи есть краткое введение.

Можно открыть больше библиотек, связанных с обработкой командной строки.awesome-go#command-lineПроверьте раздел командной строки, самая звездочкаspf13/cobraиurfave/cli, которые сложнее, чем flag/pflag, и представляют собой полнофункциональный фреймворк.

Кому интересно, может узнать.

целевой случай

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

Позвольте привести пример. Предположим, теперь вы хотите разработать инструмент управления версиями для языковой среды Go, gvg (управление версиями go by go).

Справочная информация в командной строке выглядит следующим образом:

NAME:
   gvg - go version management by go

USAGE:
   gvg [global options] command [command options] [arguments...]

VERSION:
   0.0.1

COMMANDS:
   list       list go versions
   install    install a go version
   info       show go version info
   use        select a version
   uninstall  uninstall a go version
   get        get the latest code
   help, h    Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help
   --version, -v  print the version

Эта команда содержит не только глобальные параметры, но и 8 подкоманд, некоторые подкоманды поддерживают параметры и параметры. Пока параметры опций подкоманд не указаны, и мы их увидим, когда они будут реализованы.

Далее мы пытаемся добиться этого эффекта с помощью флага. В этой статье описывается только реализация GLOBAL OPTIONS.

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

опционное представление

Самые простые команды не требуют никаких параметров и опций, а более сложные должны поддерживать настройку параметров и опций. gvg не имеет глобальных параметров, или глобальные параметры являются подкомандами, а глобальные параметры--help -hи--version -h.

Опция в пакете флага используетFlagсказал, что-hможет использоватьFlagВыражать. Опция обычно состоит из нескольких частей, таких как имя, описание использования и значение по умолчанию. если-hВыражается в коде следующим образом:

h := flag.Bool("h", false, "show help")

определяет логическое значениеFlag, по имениh,默认值是 false,使用说明为 "show help"。 Переменнаяh— логический указатель, с помощью которого можно получить значение, переданное в командной строке.

Помимо использованияflag.Bool, вы также можете использовать другой способ определенияFlag. Мы можем определить таким образом-vопции.

код показывает, как показано ниже:

var v bool
flag.BoolVar(&v, "v", false, "print the version")

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

больше типов

В дополнение к логическим типам,FlagТакже есть целые типы (int, int64, uint, uint64), числа с плавающей запятой (float64), строки (string) и длительность (time.Duration).

Предполагая, что в случае с gvg поддерживаются опции конфигурационного файла--config-path. Код реализации выглядит следующим образом:

var configPath

flag.StringVar(&configPath, "config-path", "", "config file path")

пройти черезStringVarопределить новыйFlag. Как использовать иBoolVarТо же самое, последние три параметра — это имя опции, значение по умолчанию и описание использования.

Хотя флаг поддерживает не так много встроенных типов, большинство потребностей удовлетворяются. Если у вас есть особые требования, вы также можете расширить реализацию нового типа, которая будет представлена ​​в следующей части.

длинные и короткие варианты

это сделано сейчас-hи-vДва варианта, но цель-v --versionи-h --help, то есть поддерживаются как длинные, так и короткие варианты.

ОдинFlagДолжно быть две формы, длинная и короткая, но пакет флага не поддерживает этот стиль, и для достижения цели требуется кривая, чтобы спасти страну. (Примечание: поддержка pflag упоминалась в начале этой статьи.)

здесь с-v --versionНапример, код выглядит следующим образом:

flag.BoolVar(&v, "v", false, "print the version")
flag.BoolVar(&v, "version", false, "print the version")

определяет дваFlag, который одновременно привязан к переменной. Этот эффект можно использовать толькоflag.BoolVarспособ определить новыйFlag,flag.BoolНевозможно связать одну и ту же переменную с двумя одновременноFlag.

Но на самом деле у этого тоже есть недостатки, не будем об этом, я пойму это, когда буду вводить справочную информацию позже.

разбор командной строки

определить всеFlag, и для получения правильного результата требуется еще один шаг разбора. Этот шаг очень прост, позвонитеflag.Parse()Вот и все.

Вот полный код:

package main

var h *bool
var v bool

func init() {
	flag.BoolVar(&h, "h", false, "show help")
	flag.BoolVar(&h, "help", false, "show help")
	flag.BoolVar(&v, "v", false, "print the version")
	flag.BoolVar(&v, "version", false, "print the version")
}

func main() {
	flag.Parse()
	fmt.Println("version", v)
	fmt.Println("help", h)
}

Теперь его можно скомпилировать в команду gvg.

использовать команду

Прежде чем использовать команду формально, сначала ознакомьтесь с синтаксисом флага. Согласно официальной документации, синтаксис параметра флага в командной строке имеет следующие формы.

-flag
-flag=x
-flag x // 非布尔类型才支持这种方式

Но на самом деле -- тоже поддерживается. Таким образом, вышеперечисленное может быть достигнуто--versionКривая спасает нацию.

Используйте эту команду, чтобыhelpУстановить какfalseиversionУстановить какtrue. Я пытаюсь перечислить все возможные способы его написания.

$ gvg -v
$ gvg -version -h=false  # 单个 - ,即 -version 支持
$ gvg --version=true --help=false
$ gvg --version=1 --help=0
$ gvg --version=t --help=f
$ gvg --version=T --help=F
$ gvg --version true --help true # 写法错误,因为无法识别出是 bool 值,还是参数或子命令
$ gvg -vh  # 不支持这种风格

Выполните команду и выведите результат:

version true
help false

На этом этапе вводится быстрый запуск флага. При вводе параметры остаются в подкоманде.

стиль командной строки

По некоторым историческим причинам было много разных ветвей Unix, и существует множество стандартов стиля командной строки, например:

  • Стиль Unix, параметры занимают один-добавить букву как-v, краткий вариант это он, преимущество в том, что он достаточно лаконичен;
  • BSD стиль, без вариантов-, без префикса, не знаю, как поступить в случае параметров, никаких исследований;
  • стиль GNU, используя--,как--version, длинный вариант, хорошая масштабируемость, но нужно набрать еще несколько букв;

Найдите смешной мультфильм в Интернете.

Есть два способа просмотра системного процесса:ps aux(стиль BSD) иps -elf(стиль Unix). Раньше я был очень подавлен, почему существует эта разница. Теперь я понимаю. Ха-ха.

Стиль командной строки POSIX представляет собой набор дополнений. Что такое стиль POSIX? Вы можете просмотреть этот документСинтаксис параметра команды. Он также обеспечивает стандарт для длинных и коротких опционов.

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

Суммировать

В этой статье рассказывается об использовании пакета flag в Go, которого достаточно для общих сценариев. Наконец, я вкратце рассказал о более интересной теме, стиле командной строки, есть ли ощущение, что война между программистами действительно везде.


Добро пожаловать в мой публичный аккаунт WeChat.