Motivation
実行可能なシェルスクリプトを書く際、なるべく -h
や --help
のような引数でヘルプメッセージを表示できるようにしておきたい派です。
以前はPOD形式1でファイル末尾にドキュメントコメントを書き、 pod2text
を実行して表示していたのですが、以下の理由でやり方を変えたいと思いました:
- どちらかといえばファイルの先頭に書きたい
- PODで書くと行数が長くなりがち
- 最近、PODを書く機会がほとんどないので、毎回記法を忘れている
-
pod2text
がどの環境でも動くという前提は置かない方がいいかもしれない(?)2
2ヶ月前ぐらいから悩んでいましたが、ようやくこれでよいかなというやり方にたどり着きました。
ヒアドキュメントで十分という人には無用のやり方かもしれませんが、以下で示すようなやり方にしておけば、スクリプトのフォーマットを揃えることができるでしょう。
動作確認環境
OS | Bash | AWK |
---|---|---|
Ubuntu 18.04 | v4系 | mawk 1.3.x |
Ubuntu 20.04 | v5系 | mawk 1.3.x |
macOS Mojave | v5系 | v20070501 |
macOS Catalina | v5系 | v20070501 |
結論
シェルスクリプト内に、次のようなhelp関数を定義することにしました:
# bash
help() {
awk 'NR > 2 { # シバンは出力しない
if (/^#/) { sub("^# ?", ""); print } # /^#/ にマッチしたら "^# ?" を取り除いて出力
else { exit } # /^#/ にマッチしなくなったら終了
}' $0 # 実行スクリプト自身を引数に取る
}
中でawkコマンドを呼び出して、マッチする行をヘルプメッセージとして出力します。
AWKに依存する形になりますが、POSIXの仕様を逸脱しなければ、pod2textに依存するよりはポータブルなのではないかな、と考えています。
※AWKスクリプトをもっと短く書けないの? という方はコメント欄をご確認下さい。
動作例
下のようなシェルスクリプトを書いて、ヘルプを表示してみます。
#!/usr/bin/env bash
#
# help-demo.sh
# ============
#
# Demo script to show help by shell function using AWK.
#
# Usage:
#
# help-demo.sh [-h|--help]
# Function help() shows help
help() {
awk 'NR > 2 {
if (/^#/) { sub("^# ?", ""); print }
else { exit }
}' $0
}
# help関数を実行
help
ヘルプ表示結果:
$ ./help-demo.sh --help
help-demo.sh
============
Demo script to show help by shell function using AWK.
Usage:
help-demo.sh [-h|--help]
こんな感じでMarkdown形式で書いておけば、そのままREADMEに使うこともできそうですね。
他のやり方
上の結論に至るまでに、下に挙げた参考記事などを見ながら、どうしようかと考えていました。
1つ目の参考記事にあるように、sedコマンドを用いても同様のことは実現できるようでしたが、sedのスクリプトに馴染みがなく、すぐに習熟できる気がしなかったため、AWKを使うことにしました。
(AWKスクリプトの方がhuman readableな気がしました。)
以上です。
参考記事
AWKの資料
脚注
-
ちゃんと調べきれてはいないのですが、最近クラウドに立てたVMとかには入ってなかったような… ↩