похожее на getopt поведение в Go - PullRequest
14 голосов
/ 11 ноября 2009

Как мне разобрать список параметров программы и автоматизировать обработку "--help" и / или "--version" (например, "program [-d value] [--abc] [FILE1]") в Go?

Ответы [ 8 ]

15 голосов
/ 01 октября 2014

Google создал пакет getopt (import "github.com/pborman/getopt"), который обеспечивает более стандартный анализ командной строки (по сравнению с пакетом 'flag').

package main

import (
    "fmt"
    "os"
    "github.com/pborman/getopt"
)

func main() {
    optName := getopt.StringLong("name", 'n', "", "Your name")
    optHelp := getopt.BoolLong("help", 0, "Help")
    getopt.Parse()

    if *optHelp {
        getopt.Usage()
        os.Exit(0)
    }

    fmt.Println("Hello " + *optName + "!")
}

$ ./hello --help
Usage: hello [--help] [-n value] [parameters ...]
     --help        Help
 -n, --name=value  Your name

$ ./hello --name Bob
Hello Bob!
15 голосов
/ 11 ноября 2009

Используйте пакет 'flag': http://golang.org/pkg/flag/. Однако он не использует аргументы с двойной чертой. Нет ничего, что точно имитирует поведение GNU getopt (пока).

10 голосов
/ 23 июля 2012

В разделе «Интерфейс командной строки» у вас есть несколько библиотек, способных анализировать параметры getopt-long .

Я пытался с Go1.0.2:

* * 1 022 Пример: * 1 023 *
package main

import (
    "fmt"
    goopt "github.com/droundy/goopt"
)

func main() {
    fmt.Println("flag")
    goopt.NoArg([]string{"--abc"}, "abc param, no value", noabc)

    goopt.Description = func() string {
        return "Example program for using the goopt flag library."
    }
    goopt.Version = "1.0"
    goopt.Summary = "goopt demonstration program"
    goopt.Parse(nil)
}

func noabc() error {
    fmt.Println("You should have an --abc parameter")
    return nil
}

Другие параметры по умолчанию предоставляются с goopt:

 --help               Display the generated help message (calls Help())
 --create-manpage     Display a manpage generated by the goopt library (uses Author, Suite, etc)
 --list-options       List all known flags
6 голосов
/ 09 марта 2013

go-flags очень полон, BSD лицензирован и имеет четкий пример .

var opts struct {
      DSomething string `short:"d" description:"Whatever this is" required:"true"`
      ABC bool `long:"abc" description:"Something"`
}

fileArgs, err := flags.Parse(&opts)

if err != nil {
    os.Exit(1)
}
6 голосов
/ 11 ноября 2009

Я сделал это только для вас:

package main

import (
  "fmt";
  "os"
)

func main() {
  for i, arg := range os.Args {
    if arg == "-help" {
      fmt.Printf ("I need somebody\n")
    }else if arg == "-version" {
      fmt.Printf ("Version Zero\n")
    } else {
      fmt.Printf("arg %d: %s\n", i, os.Args[i])
    }
  }
}

см. Также https://play.golang.org/p/XtNXG-DhLI

Тест:

$ ./8.out -help -version monkey business
I need somebody
Version Zero
arg 3: monkey
arg 4: business
5 голосов
/ 16 марта 2016

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

package main

import (
  "os"
  "strings"
  "gopkg.in/alecthomas/kingpin.v2"
)

var (
  app      = kingpin.New("chat", "A command-line chat application.")
  debug    = app.Flag("debug", "Enable debug mode.").Bool()
  serverIP = app.Flag("server", "Server address.").Default("127.0.0.1").IP()

  register     = app.Command("register", "Register a new user.")
  registerNick = register.Arg("nick", "Nickname for user.").Required().String()
  registerName = register.Arg("name", "Name of user.").Required().String()

  post        = app.Command("post", "Post a message to a channel.")
  postImage   = post.Flag("image", "Image to post.").File()
  postChannel = post.Arg("channel", "Channel to post to.").Required().String()
  postText    = post.Arg("text", "Text to post.").Strings()
)

func main() {
  switch kingpin.MustParse(app.Parse(os.Args[1:])) {
  // Register user
  case register.FullCommand():
    println(*registerNick)

  // Post message
  case post.FullCommand():
    if *postImage != nil {
    }
    text := strings.Join(*postText, " ")
    println("Post:", text)
  }
}

И вывод --help:

$ chat --help
usage: chat [<flags>] <command> [<flags>] [<args> ...]

A command-line chat application.

Flags:
  --help              Show help.
  --debug             Enable debug mode.
  --server=127.0.0.1  Server address.

Commands:
  help [<command>]
    Show help for a command.

  register <nick> <name>
    Register a new user.

  post [<flags>] <channel> [<text>]
    Post a message to a channel.
2 голосов
/ 20 ноября 2013

Я думаю, ты хочешь докопта. Я просто отсылаю вас к более раннему ответу Я отправил для подробностей.

1 голос
/ 18 апреля 2019

Как простая библиотека, вы имеете с августа 2017 года github.com/rsc/getopt

Чтобы использовать, определите флаги как обычно с флагом пакета. Затем введите псевдонимы, позвонив по номеру getopt.Alias:

getopt.Alias("v", "verbose")

Или позвоните getopt.Aliases, чтобы определить список псевдонимов:

getopt.Aliases(
    "v", "verbose",
    "x", "xylophone",
)

И

В общем, синтаксический анализ флага Go предпочтителен для новых программ, поскольку он не настолько педантичен в отношении количества тире, используемых для вызова флага (вы можете написать -verbose или --verbose, и программе все равно)

Этот пакет предназначен для использования в ситуациях, когда по старым причинам важно точно использовать синтаксис getopt(3), например, при переписывании в Go существующего инструмента который уже использует getopt(3).

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