他のコマンドラインパラメータプロセッサー・ゴー - CMDR [MOD]

cmdr 別のパラメータは、コマンド行プロセッサーです。

自分自身をGolang flagsコマンドライン引数の処理、しかし、都合がよい、とGoogleは常に同じ、非常にユニークな、非常に人間の行われてきました。

コンピュータの対話型インターフェースの歴史の中で、対話型のコマンドラインは、伝統と継続性を得る、つまり全体で唯一のものであるgetoptとしてもgetopt_longそういえばgetopt非難にも長い物語を伝えることができますが、この記事では、するつもりはありません。いずれにせよ、あなたは、そのインターフェースは、プログラマは、開発者は、科学者たちは、このインタフェースのためのコンピュータまたは効果的なの実務家は、すでに無償アップで、よく訓練され、既にPOSIXの一部であるのgetoptさを知る必要があります。あなたはそれを使用することはできますが、おそらくそれだけあります気付いていません。ほとんどのGNUのコマンドラインナイフは、そのようなインターフェースを採用しているので、例えば、タールのために、GWK、GZIPは、LS、 RM、...、 など、これらのツールは、このインターフェイスには表示されません。

だから、独自の方法、独自のことをやって、自分のではなく、することはできません。しかし、私はそれを購入することはできません。

まあ、これは私は、自己報酬、だけではありません。私達はちょうど、すでに優れたコマンド・ライン・インターフェースを提供するために開発されているGolangアプリケーションとのgetoptのような再版の数十を持っている、Golangオープンソース界では知る必要があります。そのような毒蛇/コブラ、CLIの傑作の不足はありませんが、いくつかの小さなリーンの実装があります。

cmdrだから、また、getoptのようなの実現。そして、既存の違いの他の実装は、CMDRは基本的にgetoptのパフォーマンスをコピーし、ということです。つまり、そのようようにcpは、mvは、およびなどの典型的なUNIX / Linuxアプリケーションは、実行する方法で、そしてベースでcmdrのアプリケーション実行する方法です。どのような問題ではなく、アプリケーションの固有のロジックを説明するためのコマンドライン引数については当然といえば。

のは、どのような特定の側面を見てみましょう。

POSIX大会

POSIXは表しポータブルオペレーティングシステムインターフェイス(英語:ポータブルオペレーティングシステムインターフェイスは、と略記POSIX)は、IEEE(電気電子学会、電気電子技術者協会)が様々なことであるUNIX オペレーティングシステムソフトウェア定義された上で実行されているAPI国際標準の名前であるのに対し正式に、IEEE STD 1003と呼ばれる相互に標準の総称、一連のISO / IEC 9945。この規格は、1985年にプロジェクトについての最初から茎。POSIXの名前はリチャード・ストールマン(RMS)が要件をIEEEと覚えやすい名前を提案しなければなりません。それは本質的にポータブルオペレーティングシステムインターフェイス(ポータブルオペレーティングシステムインタフェース)の略であり、Xは、 UnixのAPIの継承ことを示しています。電気電子学会(電気電子学会、 IEEE) UNIX環境下でのアプリケーションの移植性を向上させるために独自に開発したPOSIX標準、。しかし、POSIXは、UNIXに限定されるものではありません。そのような12月のOpenVMSとMicrosoft Windows NTなどの多くの他のオペレーティングシステムでは、POSIX標準をサポートしています。

ここでは、プログラム名、パラメータのためのPOSIX標準の規則であります:

  • プログラム名は2つの文字とより多くない9文字未満であってはなりません。
  • プログラム名は、小文字のみとアラビア数字を入れておく必要があります。
  • 「 - 」オプション名は、単一のデジタルシングルリビング特性、およびダッシュであるべき接頭辞。
  • その他のオプションオプションパラメータをマージする必要はありません。(例foo -a -b -c ---->foo -abc
  • オプションとそのパラメータの間に空白で区切られました。
  • オプション引数オプションではありません。
  • オプションの値は、それを渡すと、文字列に来る方のパラメータの場合。以下の場合myprog -u "arnold,joe,jane"の例:この場合、当社は、これらのパラメータを分離し、自分の問題を解決する必要があります。
  • オペランドが表示される前に、オプションが表示されます。
  • 特別なパラメータは、‘--'すべてのパラメータがオーバー、後続のパラメータが考慮されるオペランドであることを指定します。
  • その他のオプションの業績をカバーするためのオプションは、最後のオプションが機能する場合はオプションの配置が、しかし相互に排他的なオプション、業績を重要ではありませんどのように、オプションが繰り返された場合、注文処理。
  • 許可オペランドの順序は、プログラムの動作に影響を与えますが、ドキュメントの必要性。
  • 読み書き手順は、ファイルの単一のパラメータに指定されなければならない「 - 」標準入力または出力として意味のある処理しました。

GNUロングオプション契約

  • GNUプログラムが合意されているために、各オプションの短いPOSIXは、対応する長いオプションを持っています。
  • 短いオプションのための余分なだけの推薦を持っているために、GNUの長いオプションに対応する必要はありません。
  • 長いオプションは、最短の文字列の一意性を維持するために省略することができます。
  • または長生き空白によってパラメータおよびオプションの選択肢の間で「=」で区切られています。
  • オプションパラメータは、(短いオプションでのみ有効)はオプションです。
  • ロングオプションはダッシュで始まることができます。

getoptのインターフェース

getoptのインターフェースは、以下に記載のgetopt_longとを提供しているcmdr同一の容量を有します。

文言を以下では、短参数および短选项、そのような類似した他の語彙の概念に相当し、繰り返されることはありません。

ショートパラメータ

短いパラメータと呼ばれる単一のダッシュガイドの単一の文字のパラメータ。-v例:-dというように。時には、さらに文字の短いパラメータの2つの文字があるかもしれません。しかし、その意図は短い省略パラメータは、パラメータが短いまれ複数の文字であり、一般的に、より一般的な単一文字の短い接尾パラメータ値のように、組み合わせて使用されていることです。例のRARオプションについて-ep、-ep1、-ep3を持っています:

  ep            Exclude paths from names
  ep1           Exclude base directory from names
  ep3           Expand paths to full including the drive letter

そのプロセッサを実装する場合しかし、我々は提供することができ-ep<n>、プロセッサが十分にあるので、あなたはまだとみなすことができる-ep短いの変形パラメータ。

ロングパラメータ

2つのダッシュガイド、既知のサイズパラメータの文字複数のパラメータ。—debug例:--versionというように。

一般に、長い記述的パラメータは、より一般的に使用される単語を含み、フレーズサイズパラメータを構成します。たとえば、サブコマンドをドッカーdocker checkpoint create

$ docker checkpoint create --help

Usage:  docker checkpoint create [OPTIONS] CONTAINER CHECKPOINT

Create a checkpoint from a running container

Options:
      --checkpoint-dir string   Use a custom checkpoint storage directory
      --leave-running           Leave the container running after checkpoint

パラメータ説明

各コマンドまたはパラメータオプションは、説明のために提出することであってもよいです。

パラメータは、繰り返して積層します

かかわらず、任意の順序で表示されることがあり長さパラメータの、それはまた、任意の回数発生する可能性があります。パラメータが最後に出現方、一般的には、複数回出現するために、あまりにもカバーされる前に、登場。

コマンドラインの例の場合:-1 -a yy -a dd -a ccそれは登場していたが覆われていた、その実効値「CC」、ためのパラメータです。

ショートパラメータの組み合わせブール値

なしgetoptのパラメータの値としては、例えば"1abc"、次のコマンドラインは有効です。

  • -1 -a -b -c
  • -abc1
  • -ac -1b
  • ...

組み合わせは任意であり、順番に鈍感です。

パラメータの値が取らなければなりません

getoptのは、コロンのパラメータの後に定義され、例えばのための“1a:b::"パラメータaは、コマンドラインの形状として指定する必要があります-1 -a xxx

オプションのパラメータ値

パラメータは二つのコロンのgetopt定義された後、例えば、“1a​:b:​:"パラメータはb、コマンドラインの形状として指定する必要があります-1 -b-1 -bvalue

getoptの上の拡張インターフェイス

命令和子命令

例えば、サブドッキングウィンドウのコマンドのチェックポイント、:

graph LR
A[docker] -->|Commands| B(checkpoint)
B --> D[create]
B --> E[ls]
B --> F[rm]

実際には、コマンドとサブコマンドは、必要に応じて、のような多くのサブレベルコマンドと入れ子のコマンドレベルを作成することができ、違いはありません。このツールを使用して人に迷惑をかけるだろうしかし、実際のコマンドラインUIの設計では、ネストされたサブコマンドのつ以上の層は、非常に少ないです。

シェルオートコンプリート

現代のコマンドラインインタフェースでは、オートコンプリート(シェル完成は)の主要な特徴となっています。そのようなバッシュ、Zshの、魚のような人気のあるコマンド・ライン・インターフェースは、自動的に機能を提供します。通常、アプリケーションは、オートコンプリート機能を取得するために、このシェルの自動完全なスクリプトのサポートを提供する必要があります。

サポートアプリケーションは、このようにすることができ、自動完全なコマンドライン入力があります。

バッシュのオートコンプリート

ドッキングウィンドウのオートコンプリート

他のコマンドラインパラメータプロセッサー・ゴー -  CMDR [MOD]

zshののオートコンプリート

ドッキングウィンドウはzshの中で自動的に行わ。TABキーはzshの数はより簡潔であり、リスト選択インターフェースもより効果的でより示唆的であることに留意することができます。もちろん、zshの自動補完いくつかのバグがあり、例えば、コマンドリストのリストが破断する行の数を選択するために、視覚的なインタフェースの端末画面を超えます。

他のコマンドラインパラメータプロセッサー・ゴー -  CMDR [MOD]

使用するCMDR

cmdr できるだけ簡単に使用し、その後、我々は簡単な紹介をすることができません。

これは、単純な入口になります

package main

import (
    "fmt"
    "github.com/hedzr/cmdr"
)

func main() {
    // logrus.SetLevel(logrus.DebugLevel)
    // logrus.SetFormatter(&logrus.TextFormatter{ForceColors: true,})

    // 可选的四个选项:
    cmdr.EnableVersionCommands = true
    cmdr.EnableVerboseCommands = true
    cmdr.EnableHelpCommands = true
    cmdr.EnableGenerateCommands = true

    if err := cmdr.Exec(rootCmd); err != nil {
        fmt.Printf("Error: %v", err) // or log, logrus
    }
}

var(

    rootCmd = &cmdr.RootCommand{
        Command: cmdr.Command{
            BaseOpt: cmdr.BaseOpt{
                Name: "short",
                Flags: []*cmdr.Flag{

                },
            },
            SubCommands: []*cmdr.Command{
                serverCommands,
                // msCommands,
            },
        },

        AppName:    "short",
        Version:    cmdr.Version,
        VersionInt: cmdr.VersionInt,
        Copyright:  "austr is an effective devops tool",
        Author:     "Your Name <[email protected]>",
    }

    serverCommands = &cmdr.Command{
        BaseOpt: cmdr.BaseOpt{
            Short:       "s",
            Full:        "server",
            Aliases:     []string{"serve", "svr",},
            Description: "server ops: for linux service/daemon.",
            Flags: []*cmdr.Flag{
                {
                    BaseOpt: cmdr.BaseOpt{
                        Short:       "f",
                        Full:        "foreground",
                        Aliases:     []string{"fg",},
                        Description: "running at foreground",
                    },
                },
            },
        },
        SubCommands: []*cmdr.Command{
            {
                BaseOpt: cmdr.BaseOpt{
                    Short:       "s",
                    Full:        "start",
                    Aliases:     []string{"run", "startup",},
                    Description: "startup this system service/daemon.",
                    Action: func(cmd *cmdr.Command, args []string) (err error) {
                        return
                    },
                },
            },
            {
                BaseOpt: cmdr.BaseOpt{
                    Short:       "t",
                    Full:        "stop",
                    Aliases:     []string{"stp", "halt", "pause",},
                    Description: "stop this system service/daemon.",
                },
            },
            {
                BaseOpt: cmdr.BaseOpt{
                    Short:       "r",
                    Full:        "restart",
                    Aliases:     []string{"reload",},
                    Description: "restart this system service/daemon.",
                },
            },
            {
                BaseOpt: cmdr.BaseOpt{
                    Full:        "status",
                    Aliases:     []string{"st",},
                    Description: "display its running status as a system service/daemon.",
                },
            },
            {
                BaseOpt: cmdr.BaseOpt{
                    Short:       "i",
                    Full:        "install",
                    Aliases:     []string{"setup",},
                    Description: "install as a system service/daemon.",
                },
            },
            {
                BaseOpt: cmdr.BaseOpt{
                    Short:       "u",
                    Full:        "uninstall",
                    Aliases:     []string{"remove",},
                    Description: "remove from a system service/daemon.",
                },
            },
        },
    }
)

私たちは、違いが大きいcmdr.RootCommandとcmdr.Commandが、アプリケーション情報の分野の多くのメンバーではないことがわかります。cmdr.Flagがcmdr.Commandが大きくない区別そして、それらはすべてBaseOptフィットと同じ構造を有しています。

したがって、カスタムコマンドとカスタムオプションは、ネストされた構造を修正する必要があり、非常によく似ています。ネストされた構造が混乱目である場合、サブコマンドは、抽出された、または独立変数に、サブコマンドのグループ、次いで方法優れた注文の適切な位置への参照を使用して埋め込むことができます。

この実施形態はまた、抽出されたシェア同様の構造に適しているが、参照とディープコピーの違いに注意を払うこと。さらにここでは説明しません、要するに、あなたがわからないと感じた場合、正直に一般的なツールの開発は、あまりにも多くのネストされたバーを持たないであろう定義するためにレベルを完了したいです。

ホームに近づいた後、上記の定義の完了は、あなたが(または実行main.goを行く)コンパイルされた実行可能ファイルを実行することができます。あなたは、端末でそれを使用しようとすることができます。

bin/short
bin/short --help
bin/short --version
bin/short -#
bin/short --debug --verbose server --help
bin/short svr --help --debug -v
bin/short s start -f ~~debug

指定されたアクション

各コマンドは、( cmdr.Command割り当てることができるActionFUNCオブジェクト。あなたはここにビジネスロジックの作成を発注したいと思うでしょう。

如果有必要的话,一个选项(cmdr.Flag)也可以被提供一个 Action,如果你需要在选项被扫描到时触发点其他逻辑的话。

对于命令而言,你可以提供额外的 PreActionPostAction,它们分别是在命令的 Action 被执行的前后被调用的。特别是 PreAction 允许返回一个特别的错误值 cmdr.ShouldBeStopException 来告诉 cmdr 终止后续处理,所以你可以有机会避免 命令的 Action 部分被执行。

由于 RootCommand 也是一个 Command,所以定义在 RootCommand 中的 PreActionpostAction 有着特别的处理逻辑:

RootCommand.PreAction 将会在具体 Command.PreAction 执行之前被执行;RootCommand.PostAction 将会在具体 Command.PostAction 执行之后被执行。

这样的特别逻辑是为了便于开发者定义自己的前置、退出逻辑。例如一个微服务应该在开始提供服务之前完成注册中心登记,以及在停止服务时撤销登记,这些任务适合于在 RootCommandPre/PostAction 中来做。

~~debug

~~debug 是一个隐藏性的标志。~~ 和 long 参数 是相似的,不过它的不同在于,相应的参数的入口不会被建立在 标准名字空间中,因此你需要在顶级名字空间中抽取它的值。

~~debug 有着一个特别的作用,在调试阶段,这个选项将会使得正常处理逻辑结束后,附加一段调试性的信息输出,其中包含 所有有效的选项及其最终值,还包含这些选项的 yaml 文本形式。

一个式样是:

他のコマンドラインパラメータプロセッサー・ゴー -  CMDR [MOD]

你可以通过:

bin/wget-demo ~~debug

来查看相似的输出结果。

我相信这个功能可以帮助你解决很多问题,不必再来猜来猜去的了。

名字空间

所有的选项值都被放在标准名字空间中,cmdr.RxxtPrefix 定义了标准名字空间的层级,其默认值为 app

这意味着 RootCommand 的 Flags,例如 --version ,可以用 cmdr.GetBool("app.version") 来抽取其值。类似的,--debug 的抽取语句为 cmdr.GetBool("app.debug")

前面说过 ~~debug 有点特殊,这样的不加前缀的选项的值可以直接抽取:cmdr.GetBool("debug")

每一级命令或子命令就会建立一个嵌套的名字空间,其名称取自命令的 Full 字段,也就是长参数名。因此 bin/short server start -f-f 的抽取语句为 cmdr.GetBool("app.server.start.foreground")

你当然可以执行不同的 cmdr.RxxtPrefix,例如:

cmdr.RxxtPrefix = []string{"server",}
// 等价于使用 ”server.xxx" 而不是 “app.xxx”

一个选项的值是可以多种形态的,但总的来说我们支持四种数据类型:

  • bool
  • int
  • string
  • string slice

更多的类型,我们暂不直接支持。未来或会予以增强。

环境变量重载

可以使用环境变量重载去覆盖命令行参数。

所以:

CMDR_APP_SERVER_START_FOREGROUND=1 bin/short server start 等价于 bin/short server start -f

如果你希望使用非 ”CMDR_“ 的环境变量前缀,你可以设置 cmdr.EnvPrefix 来自行控制前缀。例如

cmdr.EnvPrefix = []string{ "Rx", "cd", }
// 等价于使用 RX_CD_ 前缀
当前版本的问题

环境变量的优先级较低,如果配置文件或者命令行参数有指定值,则环境变量的设定值就被掩盖了。

这不符合惯例,我们考虑在下一版本中解决此问题。

我们将会实现的优先级为:defaultValue -> config-file -> env-var -> command-line opts。

配置文件的自动加载

默认情况下,cmdr 自动查看如下文件:

  • /etc/&lt;appname&gt;/&lt;appname&gt;.yml
  • /usr/local/etc/&lt;appname&gt;/&lt;appname&gt;.yml
  • $HOME/.&lt;appname&gt;/&lt;appname&gt;.yml

cmdr 也会自动装载相应的 conf.d 子目录中的所有 yaml 文件,并依次载入和覆盖选项的定义值。因此你可以切分大型配置文件到多个小文件中,以便于运维部署和管理。

对于开发者来说,cmdr 还会首先检查项目目录下的 ./ci/etc/&lt;appname&gt;/&lt;appname&gt;.yml 是否有效并试图自动加载它及其 conf.d 子目录。

cmdr 支持 conf.d 文件夹的监视,其中的变化会被传送给所有注册的 listeners。关于这个方面的细节,可以查看:

  • cmdr.AddOnConfigLoadedListener(c)
  • cmdr.RemoveOnConfigLoadedListener(c)
  • cmdr.SetOnConfigLoadedListener(c, enabled)
当前版本的问题

无法定制加载位置、无法忽略加载位置,等等。

其他的配置文件格式也暂时不支持。

实例 wget-demo

我们已经实现了一个 wget 的命令行界面复刻版本,但是仅提供小部分命令行参数的处理,因为完整的复刻版本基本上只是一个重复的劳作了,作为示例我们已经实现了足够多的选项,足以说明 cmdr 的能力了。

wget-demo 的帮助屏是这样的:

他のコマンドラインパラメータプロセッサー・ゴー -  CMDR [MOD]

和 gnu 的 wget 相比较而言,看起来也算是没有区别了。

wget-demo 的源码可以在这里找到:

https://github.com/hedzr/cmdr/examples/wget-demo/

cmdr 的版本规划

semver是符合规范的。

关于 semver 的含义可以查看如下两个链接,无需多言:

更多的介绍

cmdr 是在早前若干个非正式实现的基础上重写的一个新的实现,其首要目标就是完完全全地 Unix/Linux 命令行界面,而不是 golang 风格的、或者其它的部分实现的风格。

getoptそして、getopt_long独自のパラメータに定義された方法がありますが、この点で、cmdrそれは便利ではないので、そのシミュレーションのスタイルを実装する予定はありませんすることはあまり直感的ではありません。

cmdrすべてを完了するために、定義されたコマンドとパラメータの完了後にそれを行うようにしてください。また、あなたはあなたが得ることができる他に何もする必要はありません。

  • 自動ヘルプ画面
  • 自動コンフィギュレーションファイルがロードされ
  • プロファイルはに割り当てられたカットconf.dのサブディレクトリ、および変更を自動的に監視します
  • UNIX / LinuxのコマンドラインUIを完了
  • 環境変数は、オプションを再ロードすることを許可します
  • シェルは自動補完機能をサポートしています。
  • 詳細はこちら...

今も、我々は改善のパワーへの投資を継続する必要があり、主な特徴のほとんどは、詳細は完璧なポリッシュには至っていないことを実現します。しかし、主な目的として達成されたとして構築されてきました。

その他のcmdr使用法、説明は今後も継続されます。

参照

おすすめ

転載: blog.51cto.com/8547209/2403673