[linux]そうだ、manpage作ろう

2016年12月5日月曜日

linux シェルスクリプト

シェルスクリプトのようなコマンドラインツールを作成した時に使い方をreadmeファイルで提供することはよくある。
これをreadmeファイルではなく、もっとかっこよく提供したい。manやHTMLのように。

そんなときは、help2manを使ってみるといいかもしれない。
'help2man' Reference Manual

help2manは任意のコマンドに"--help","--version"オプションを与えて起動して、標準出力の内容からmanファイルを生成してくれる。

例えば、catコマンドのmanを作りたければ、以下のようにする。

$ help2man -o cat.1 cat

"-o"オプションで出力ファイルを指定しなければ、生成結果は標準出力に出る。
デフォルトではLOCALE=Cで生成されるので、日本語にしたければ"-L"でシステムで使用しているロケールを指定しよう。
また、デフォルトだと関連項目にTexinfoマニュアルの紹介が出力されてしまうけど、これは"-N"オプションで抑止できる。

$ help2man -N -Lja_JP.utf8 -o cat.1 cat

manコマンドは引数に"/"が入っているとキーワードではなく、ファイル名だと認識するので、作成したmanファイルを見るには以下のようにする。

$ man ./cat.1

もちろん手書きでmanファイルを作成することもできるけど、Javadocみたいにスクリプトから自動生成できると楽だし、"--help","--version"オプションで表示する内容で一元管理できるところがいい。

次にmanからHTMLに変換してみよう。
これにはgroffコマンドの"-Thtml"オプションを使おう。

$ groff -Wchar -mandoc -Dutf8 -Thtml cat.1 >cat.1.html

基本的には"-mandoc -Thtml"オプションをつければ、manからHTMLに変換されるけど、文字化けする場合は-Dutf8のように明示的に入力ファイルの文字コードを指定しよう。
また、UTF-8変換時に存在しない文字の警告が表示される場合、-Wcharで抑止できる。

じゃあ、help2manが理解できるhelpやversionの形式はどうなっていればいいんだろうか。
helpは以下の形式になっていればいいみたい。
使用法: コマンドの形式
コマンドの概要
(空行)
  オプションの説明
  ...
(空行)
例:
  ...
(空行)
バグの報告

versionは以下で。
バージョン情報
Copyright 著作権表示
(空行)
作者 作者名

実際の例はこんな感じ。

man2html.sh
#!/bin/sh

usage() {
  cat <<'EOF'
使用法: man2html.sh [オプション] ファイル
man形式のファイルを読み込んで、html形式に変換し、標準出力に出力します。

  -h, --help    この使い方を表示して終了する
  -v, --version バージョン情報を表示して終了する

例: 
  man2html.sh man2html.sh.1     ファイルの内容をhtml形式に変換し、標準出力に出力します。

man2html.sh のバグを発見した場合は ブログにコメントしてね。
EOF
}

version() {
  cat <<'EOF'
man2html.sh 1.0
Copyright (C) 2016 SG sgnet.co.jp
例なので、自由に使っていいよ。

作者 Takehiko Ichioka
EOF
}

if [ "$1" = '-h' -o "$1" = '--help' ]
then
  usage
  exit 0
fi

if [ "$1" = '-v' -o "$1" = '--version' ]
then
  version
  exit 0
fi

groff -Wchar -mandoc -Dutf8 -Thtml $1
$ help2man -N -Lja_JP.utf8 -o man2html.sh.1 ./man2html.sh
$ ./man2html.sh man2html.sh.1 >man2html.sh.1.html

manとHTMLの表示はこんなふうになる。