はじめに
「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」20日目の記事は、Goを使ったCLIツール開発についてです。
バックエンド開発において実際に使えるツールを制作するとしたら、CLIが身近なのではないかと思います。
この記事では、Go言語を使ってシンプルなCLIツールを開発する基礎的なステップを解説します。
- 日々の開発業務の中で「この作業、もっと楽にできないかな?」と感じている方
- Goを使って何か実用的なものを作ってみたいと考えている方
この記事で、Goでコマンドライン引数を受け取り、それに応じて動作するシンプルなCLIツールを作る仕組みを理解できるよう、一緒に頑張りましょう!
CLIツールとは?
CLI (Command Line Interface) ツールとは、ターミナルやコマンドプロンプトなどの黒い画面(コマンドライン)から、コマンドを入力して操作するソフトウェアのことです。
普段私たちが何気なく使っているgit, ls, docker, npmなども、すべてCLIツールの一種です。
GUI(グラフィカルな画面)を持つアプリケーションとは異なり、CLIツールはテキストベースで動作するため、以下のような利点があります。
- 自動化との親和性: シェルスクリプトなどと組み合わせることで、複数のコマンドを連続して実行したり、定期的に実行したりといった処理の自動化が容易です。
- 軽量・高速: グラフィカルな要素がないため、一般的に動作が軽量で高速です。
- リモート操作: SSHなどを通じて、リモートサーバー上でも手軽に実行できます。
CLIツールは、日々の開発業務における様々な場面で活躍します。
例えば、大量のファイル名を一括で変更したり、プロジェクトのビルドやデプロイを自動化したり、CSVファイルから必要な情報を抽出したりと、その用途は多岐にわたります。
GoがCLIツール開発に向いている理由
Go言語は、その言語仕様やエコシステムから、CLIツールの開発に非常に向いていると言われています。
-
シングルバイナリとしてコンパイルできる: Goで作成したプログラムは、
go buildコマンド一つで、依存関係をすべて含んだ単一の実行可能ファイル(バイナリ)にコンパイルされます。これにより、実行環境にGoのランタイムを別途インストールする必要がなく、作成したバイナリファイルをコピーするだけで、どこでもツールを実行できます。 - クロスコンパイルが容易: macOS上で開発しながら、Windows用やLinux用の実行ファイルを簡単に作成できます。これにより、チームメンバーが異なるOSを使っていても、同じツールを共有することが容易です。
- 標準ライブラリが豊富: ファイル操作、ネットワーク通信、コマンドライン引数のパースなど、CLIツール開発で必要となる多くの機能が、標準ライブラリだけで十分に提供されています。
これらの特徴から、現代の開発シーンで広く使われている多くのCLIツールがGoで開発されています。
コマンドライン引数の受け取り方
CLIツールが外部から情報を受け取る最も基本的な方法がコマンドライン引数です。
Goでは、標準ライブラリのosパッケージを使うことで、コマンドライン引数を簡単に受け取ることができます。
プログラム実行時に渡されたコマンドライン引数は、os.Argsという文字列のスライス(配列)に格納されます。
-
os.Args[0]: 実行されたプログラム自身の名前(パス) -
os.Args[1]: 1番目の引数 -
os.Args[2]: 2番目の引数 - ...
簡単な例を見てみましょう。
main.go
package main
import (
"fmt"
"os"
)
func main() {
// os.Argsはコマンドライン引数を格納した文字列のスライス
args := os.Args
fmt.Printf("渡された引数の数: %d\n", len(args))
fmt.Printf("os.Args の中身: %v\n", args)
// os.Args[0] はプログラム名
fmt.Printf("プログラム名: %s\n", args[0])
// 引数が1つ以上渡されているかチェック
if len(args) > 1 {
fmt.Printf("1番目の引数: %s\n", args[1])
}
if len(args) > 2 {
fmt.Printf("2番目の引数: %s\n", args[2])
}
}
実行例:
# 引数なしで実行
$ go run main.go
渡された引数の数: 1
os.Args の中身: [/var/folders/.../main]
プログラム名: /var/folders/.../main
# 引数を2つ渡して実行
$ go run main.go hello world
渡された引数の数: 3
os.Args の中身: [/var/folders/.../main hello world]
プログラム名: /var/folders/.../main
1番目の引数: hello
2番目の引数: world
このように、os.Argsを参照するだけで、非常に簡単にコマンドラインからの入力を受け取ることができます。
【実践】シンプルなファイル操作CLIツールの作成
それでは、これまでの知識を活かして、簡単なファイル操作を行うCLIツールを作成してみましょう。
要件:
-
createfile <ファイル名> <内容>というコマンドを実行すると、指定したファイル名で、指定した内容のテキストファイルを作成する。 - 引数が不足している場合は、使い方を表示して終了する。
main.go
package main
import (
"fmt"
"os"
)
func main() {
// コマンドライン引数を取得
args := os.Args
// 引数の数をチェック (プログラム名 + ファイル名 + 内容 の3つが必要)
if len(args) < 3 {
fmt.Println("使い方: createfile <ファイル名> <内容>")
fmt.Println("例: createfile hello.txt \"Hello, World!\"")
os.Exit(1) // エラーコード1で終了
}
// 引数からファイル名と内容を取得
fileName := args[1]
content := args[2]
// ファイルを作成し、内容を書き込む
// os.WriteFile はファイル作成、書き込み、クローズを一度に行う便利な関数
err := os.WriteFile(fileName, []byte(content), 0644)
if err != nil {
fmt.Fprintf(os.Stderr, "エラー: ファイルの書き込みに失敗しました: %v\n", err)
os.Exit(1)
}
fmt.Printf("ファイル '%s' を作成しました。\n", fileName)
}
バイナリファイルの作成と実行
Goで作成したCLIツールは、go buildコマンドで単一の実行可能ファイル(バイナリ)にコンパイルできます。
ビルド
ターミナルで、main.goがあるディレクトリで以下のコマンドを実行します。
# 'createfile' という名前のバイナリを作成する
go build -o createfile
実行
ビルドが完了すると、カレントディレクトリにcreatefileという実行可能ファイルが生成されます。
このファイルは、Goがインストールされていない環境でも動作します。
ターミナルから、このバイナリを直接実行してみましょう。
# 使い方を表示させる
$ ./createfile
使い方: createfile <ファイル名> <内容>
例: createfile hello.txt "Hello, World!"
# 実際にファイルを作成する
$ ./createfile mynote.txt "これはCLIツールから作成したメモです。"
ファイル 'mynote.txt' を作成しました。
# 作成されたファイルの中身を確認
$ cat mynote.txt
これはCLIツールから作成したメモです。
応用編:パスを通す
作成したcreatefileバイナリを、/usr/local/binや~/binのような、システムのPATH環境変数に含まれるディレクトリに移動させることで、どのディレクトリからでもcreatefileコマンドを実行できるようになります。
これでCLIを、いつでも手軽に呼び出せるようになりました。
おわりに
この記事では、os.Argsを使った、簡単なCLIツール制作の方法を紹介しましたが、Goには-vや--fileのような、もっと複雑なフラグ(オプション)を扱うためのflagパッケージが標準で用意されています。
さらに、cobraのような本格的なCLIツールを開発できる外部ライブラリもあるので、今後はこれらのライブラリも活用しつつ、実用的な便利ツール開発に挑戦していきたいなと感じました。
最後までお読みいただき、ありがとうございました!
この「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」では、GoやJavaを使い、APIの作り方、データベースとの接続、テストやDockerといった気になったバックエンド技術の基本を振り返った学びを共有しています。
ぜひ他の記事もチェックして、筆者がこのひとりアドカレを完遂することができるか、確認してみてください(^^)
学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025
それでは、明日の「学生ひよこ界隈が送るGo/Javaで実現する「はじめてのバックエンド」Advent Calendar 2025」の記事もお楽しみに!