Goで標準入力とファイル読み込みを可能にするインタフェース

kaneshin
kaneshin
Feb 1 · 4 min read

シェルではパイプを利用して標準入力から文字列を読み込み、標準出力へ出力することが多いですが、CLIではオプションや引数でファイル名を渡し、直接ファイルを読み込むこともあります。

Go言語でそのようなパターンをサポートするときに皆さんどうやって書いているのか気になったので、自分のテンプレを紹介します。

結論

意図はわかったからコード見せろという人向け👾

var r io.Reader
switch filename {
case "", "-":
r = os.Stdin
default:
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
r = f
}

コマンドで表現する

ひとまず、 file.dat という名前で適当な文字列が書き込まれているファイルを用意します。

$ cat file.dat
foobar

このファイルを /bin/reverse という文字列一行ずつ反転するコマンドを作ったとして、下記の3つのインタフェースを提供したい場合です。

$ cat file.dat | /bin/reverse
raboof
$ cat foobar | /bin/reverse -
raboof
$ /bin/reverse file.dat
raboof

CLIツールを作るときは POSIX の Utility Syntax Guidelines に沿ってコマンドを定義しているので、大体このようにいつも準備しています。

ダッシュ を使って標準入力から読み込ませるのはコマンドの意図に合わせてください。ダッシュはコマンドの利用のされ方では標準出力にもなり得るし、使用されないこともあります。詳しくは IEEE に仕様があるはずです。

コードで表現する

冒頭に書いたのと大差ないですが、このように記述しています。

var filename string
if args := flag.Args(); len(args) > 0 {
filename = args[0]
}
var r io.Reader
switch filename {
case "", "-":
r = os.Stdin
default:
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
r = f
}

読み込むようの変数を io.Reader で定義し、ファイル名が無いかダッシュだった場合は os.Stdin を設定、そうでない場合はファイルを読み込みます。

コマンドの引数が複数あるとかは各々カスタマイズしてください。けれど、大体これでいいんじゃないかと思っている。

コード全体

これは文字列をリバースするとかは実装していないです。ただ単に受け取った文字列を標準出力に出力しているだけです。

ちなみに、正常に標準入力かファイル名が渡ってこない場合は実行待ちになります。実行待ちとならないように工夫もできますが、パイプでコマンドを連鎖させるときは待ちや失敗のような異常系で止まることも重要なので、インタフェース違反が起きたら異常のまま処理をすすめます。

例えば、やりがちな例だとインタフェース違反をしたときにツール側では空文字列で処理をしてしまうなどをして正常に処理させるような対応はしていないです。(しないほうがいいです)

おわりに

ここらへんのインタフェースデザインは気になるのでみなさんの実装を見てみたいです😎

Utility Syntax Guidelines を読みたい方はこちらから

Eureka Engineering

Learn about Eureka’s engineering efforts, product developments and more.

kaneshin

Written by

kaneshin

Hi, I’m kaneshin. I’m currently working as an engineer based in Tokyo, Japan.

Eureka Engineering

Learn about Eureka’s engineering efforts, product developments and more.

More From Medium

More from Eureka Engineering

More on Engineer from Eureka Engineering

More on Engineer from Eureka Engineering

More on Engineer from Eureka Engineering

Go言語の思想とエウレカでの5年間の活用

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade