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の、魚のような人気のあるコマンド・ライン・インターフェースは、自動的に機能を提供します。通常、アプリケーションは、オートコンプリート機能を取得するために、このシェルの自動完全なスクリプトのサポートを提供する必要があります。
サポートアプリケーションは、このようにすることができ、自動完全なコマンドライン入力があります。
バッシュのオートコンプリート
ドッキングウィンドウのオートコンプリート
zshののオートコンプリート
ドッキングウィンドウはzshの中で自動的に行わ。TABキーはzshの数はより簡潔であり、リスト選択インターフェースもより効果的でより示唆的であることに留意することができます。もちろん、zshの自動補完いくつかのバグがあり、例えば、コマンドリストのリストが破断する行の数を選択するために、視覚的なインタフェースの端末画面を超えます。
使用する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
)割り当てることができるAction
FUNCオブジェクト。あなたはここにビジネスロジックの作成を発注したいと思うでしょう。
如果有必要的话,一个选项(cmdr.Flag
)也可以被提供一个 Action
,如果你需要在选项被扫描到时触发点其他逻辑的话。
对于命令而言,你可以提供额外的 PreAction
和 PostAction
,它们分别是在命令的 Action
被执行的前后被调用的。特别是 PreAction
允许返回一个特别的错误值 cmdr.ShouldBeStopException
来告诉 cmdr
终止后续处理,所以你可以有机会避免 命令的 Action 部分被执行。
由于 RootCommand
也是一个 Command
,所以定义在 RootCommand
中的 PreAction
,postAction
有着特别的处理逻辑:
RootCommand.PreAction
将会在具体 Command.PreAction
执行之前被执行;RootCommand.PostAction
将会在具体 Command.PostAction
执行之后被执行。
这样的特别逻辑是为了便于开发者定义自己的前置、退出逻辑。例如一个微服务应该在开始提供服务之前完成注册中心登记,以及在停止服务时撤销登记,这些任务适合于在 RootCommand
的 Pre/PostAction
中来做。
~~debug
~~debug
是一个隐藏性的标志。~~
和 long 参数 是相似的,不过它的不同在于,相应的参数的入口不会被建立在 标准名字空间中,因此你需要在顶级名字空间中抽取它的值。
~~debug
有着一个特别的作用,在调试阶段,这个选项将会使得正常处理逻辑结束后,附加一段调试性的信息输出,其中包含 所有有效的选项及其最终值,还包含这些选项的 yaml 文本形式。
一个式样是:
你可以通过:
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/<appname>/<appname>.yml
/usr/local/etc/<appname>/<appname>.yml
$HOME/.<appname>/<appname>.yml
cmdr
也会自动装载相应的 conf.d
子目录中的所有 yaml 文件,并依次载入和覆盖选项的定义值。因此你可以切分大型配置文件到多个小文件中,以便于运维部署和管理。
对于开发者来说,cmdr
还会首先检查项目目录下的 ./ci/etc/<appname>/<appname>.yml
是否有效并试图自动加载它及其 conf.d 子目录。
cmdr
支持 conf.d 文件夹的监视,其中的变化会被传送给所有注册的 listeners。关于这个方面的细节,可以查看:
cmdr.AddOnConfigLoadedListener(c)
cmdr.RemoveOnConfigLoadedListener(c)
cmdr.SetOnConfigLoadedListener(c, enabled)
当前版本的问题
无法定制加载位置、无法忽略加载位置,等等。
其他的配置文件格式也暂时不支持。
实例 wget-demo
我们已经实现了一个 wget 的命令行界面复刻版本,但是仅提供小部分命令行参数的处理,因为完整的复刻版本基本上只是一个重复的劳作了,作为示例我们已经实现了足够多的选项,足以说明 cmdr
的能力了。
wget-demo 的帮助屏是这样的:
和 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
使用法、説明は今後も継続されます。