Goのflagパッケージを使ってコマンドライン引数でフラグを扱うの続き

前回の続きでflagパッケージについて書きます。

Usage

間違ったフラグを渡したときなどにUsageが表示されますが、flag.Usageに関数を入れることでカスタマイズできます。
デフォルトだと以下のようになっています。


var Usage = func() {
	fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0])
	PrintDefaults()
}

”Usage of プログラム名”の後にPrintDefaultsでフラグの説明を表示しています。
詳細な使用方法を出したい時などに使えます。

PrintDefaults

フラグのデフォルト値や説明を表示します。

NFlag

パースが成功したフラグ数を返します。

NArg

パース後に残ったコマンドライン引数の数を返します。

フラグの前にフラグではないコマンドライン引数を使いたい場合

FlagSetで実現できます。

まずflag.NewFlagSetでFlagSetを作成します。


flag.NewFlagSet(string, ErrorHandling) *FlagSet

flagSet := flag.NewFlagSet(os.Args[0], flag.ExitOnError)

最初の引数はプログラムの名前を入れるのでos.Args[0]を渡します。
二番目はパースエラーが起きた時の動作を指定します。

  • "ContinueOnError"はプログラムの実行を続行します。
  • ”ExitOnError”は通常のflagのデフォルト設定で、os.Exit(2)を呼びます。
  • "PanicOnError"はPanicします。

FlagSetには通常のフラグ設定をする関数と同じ名前のメソッドがあるので、同じようにフラグを定義します。
パースにはstringのスライスを渡せるので、フラグである引数を渡します。


func (f *FlagSet) Parse(arguments []string) error

flagSet.Parse(os.Args[3:])
サンプルコード

package main

import (
    "flag"
    "fmt"
    "os"
)

var (
    input  string
    output string
)

const (
    defaultInput  = "input.txt"
    defaultOutput = "output.txt"
    inputUsage    = "入力ファイル"
    outputUsage   = "出力ファイル"
)

func main() {
    //FlagSetを作成
    flagSet := flag.NewFlagSet(os.Args[0], flag.ExitOnError)
    //flag設定
    flagSet.StringVar(&input, "input", defaultInput, inputUsage)
    flagSet.StringVar(&input, "i", defaultInput, inputUsage+" 短縮版")
    flagSet.StringVar(&output, "output", defaultInput, outputUsage)
    flagSet.StringVar(&output, "o", defaultInput, outputUsage+" 短縮版")
    //Usageの表示をカスタム
    flagSet.Usage = func() {
        fmt.Fprintf(os.Stderr, "%s の使用方法\n", os.Args[0])
        //フラグのデフォルト設定や説明を表示
        flagSet.PrintDefaults()
    }
    //最初の二つのフラグでないコマンドライン引数を取得
    if len(os.Args) < 3 {
        os.Exit(1)
    }
    arg1 := os.Args[1]
    arg2 := os.Args[2]
    // 三個目以降をフラグとしてパース
    flagSet.Parse(os.Args[3:])
    //引数とフラグを表示
    fmt.Printf("arg1[%s]\n", arg1)
    fmt.Printf("arg1[%s]\n", arg2)
    fmt.Printf("output[%s]\n", output)
    fmt.Printf("input[%s]\n", input)
}

サンプルではフラグの前の引数の数は固定ですが、可変だと手動で調べないといけないのでちょっと面倒ですね。

この記事へのコメント

最近のトラックバック