プログラム実行時にコマンドライン引数を渡すことができるGoのプログラムをいくつか書き始めてみましょう。これはとても簡単で、Goのプログラムを実行するときにカスタムの引数を渡すことができます。私たちもカスタム引数を作ってみましょう。
Golangでのコマンドライン引数の操作
Golangにおける引数の渡し方は、プログラム名と一緒にスペースで区切った形で引数を置いてください。
$ go run main.go 引数1 引数2
os パッケージ
osパッケージには、Args配列が含まれています。Args配列は、渡されたすべてのコマンドライン引数を含む文字列配列です。最初の引数であるプログラム名を見てみましょう。これは全く渡す必要がありません。
次のコードは、コマンドラインにプログラム名を表示します。
package main
import (
"os"
"fmt"
)
func main() {
// 第一引数はプログラム名を表示する
programName := os.Args[0]
fmt.Println(programName)
}
実行結果は以下の通り
$ go run main.go
/var/folders/hs/mhmd0pnn7y58mz_dflt3pjh00000gn/T/go-build1573699510/b001/exe/main
CLIの引数の数
コマンドラインで渡された引数の数を簡単に得ることができます。そのためには、len()関数を使います。
以下は、渡された引数の長さを表示するコードです。
package main
import (
"fmt"
"os"
)
func main() {
argLength := len(os.Args[1:])
// use fmt.Printf() to format string
fmt.Printf("Arg length is %d\n", argLength)
}
スライスを使って、最初の引数以外のすべての引数を持っています。
$ go run main.go a b c d
Arg length is 4
渡されたコマンドライン引数の反復処理
コマンドラインから渡された引数を繰り返し処理するために、os.Args配列をループします。
以下、その方法をご紹介します。
package main
import (
"fmt"
"os"
)
func main() {
// the first argument i.e. program name is excluded
argLength := len(os.Args[1:])
fmt.Printf("Arg length is %d\n", argLength)
for i, a := range os.Args[1:] {
fmt.Printf("Arg %d is %s\n", i+1, a)
}
}
実行結果は次のとおりです。
$ go run main.go a b c d
Arg length is 4
Arg 1 is a
Arg 2 is b
Arg 3 is c
Arg 4 is d
カスタム引数の作成
それでは、カスタムCLI引数を実装するためのフラグを作成してみましょう。
flagパッケージ
フラグを実装するために、flagというパッケージを使用します。例として、フェイクのログイン機構を作ってみます。
以下は、フェイクログインシステムのコードです。
package main
import (
"flag"
"fmt"
)
func main() {
// variables declaration
var uname string
var pass string
// flags declaration using flag package
flag.StringVar(&uname, "u", "root", "Specify username. Default is root")
flag.StringVar(&pass, "p", "password", "Specify pass. Default is password")
flag.Parse() // after declaring flags we need to call it
// check if cli params match
if uname == "root" && pass == "password" {
fmt.Printf("Logging in")
} else {
fmt.Printf("Invalid credentials!")
}
}
実行結果は以下の通りです。
$ go run main.go -u root -p password
Logging in
誤った値の挿入
間違った値を挿入すると、エラーが発生し、そのフラグの正しい使い方を教えてくれます。たとえば、文字列フラグを使用しているときに数値を入力すると、エラーが発生し、正しい使い方がコンソールに表示されます。
$ go run main.go -u22 -p45
flag provided but not defined: -u22
Usage of /var/folders/hs/mhmd0pnn7y58mz_dflt3pjh00000gn/T/go-build997181123/b001/exe/main:
-p string
Specify pass. Default is password (default "password")
-u string
Specify username. Default is root (default "root")
exit status 2
カスタムユースの作成
flag.Usageを使用して、間違った使用方法の後に表示されるカスタム使用法の文字列を定義することができます。それにより、表示方法をカスタマイズすることができます。
package main
import (
"flag"
"fmt"
)
func main() {
var name string
flag.StringVar(&name, "n", "admin", "Specify name. Default is admin.")
flag.Usage = func() {
fmt.Printf("Usage of our Program: \n")
fmt.Printf("./go-project -n username\n")
// flag.PrintDefaults() // prints default usage
}
flag.Parse()
}
以下が間違えた入力をした時の実行結果です。
$ go run main.go -n123
flag provided but not defined: -n123
Usage of our Program:
./go-project -n username
exit status 2