- 環境はMac前提
- 以下は実行可能ファイルとしてパスを通して利用する場合を想定する
Usage関数
- シェルスクリプトの
-h
オプションで説明文を表示する際に、内部で関数化されている例がよくある - しかし、これは本来変数的に扱いたい説明文を関数として扱っているので気分がよろしくない
- 実際的な問題としては、改行が気持ちよく書けない
whatコマンド用説明文
- 以下のように記述すると、
what
コマンドの引数にスクリプトファイルを取った場合に表示できる-
@(#)
の後に記述した文字列が表示される- つまり
echo '@(#)hoge'
とかいうコマンドが含まれていればhoge
と表示される
- つまり
- 普通はコメントアウトして書く
- スクリプト内のどこに書いても良い
-
- これだとコメントを文字列的に扱えるので気分が良い
- 調べてみたが正式な呼び名は見付からなかった。whatのmanでは、
@(#)
は単に「marker」、その後の文字列は単に「description」と書かれていた。
sample.sh
# @(#)This is sample script.
# @(#)Usage: sample.sh
pwd # @(#)print current working directory.
$ what ~/bin/sample.sh
sample.sh
This is sample script.
Usage: sample.sh
print current working directory.
シェルスクリプト内のオプション解析等で利用する
- Usage関数の代わりに
what
コマンドを利用すれば良い -
$0
変数はスクリプトファイルの絶対パスに置き換えられる
sample.sh
# !/bin/bash
# @(#)This is sample script.
# @(#)Usage: sample.sh [-h]
readonly SCRIPTNAME="$(basename "$0")"
while getopts h OPT
do
case "$OPT" in
h)# @(#) -h: print help
what "$0" 1>&2
exit 0
;;
?)
echo "$SCRIPTNAME: ERROR - Undifined option." 1>&2
what "$0" 1>&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
pwd # @(#)print current working directory.
$ sample.sh -h
/Users/catfist/bin/sample.sh
This is sample script.
Usage: sample.sh [-h]
-h: print help
print current working directory.
難点
- コメント内で変数が使えない。
- 従って、スクリプトファイル名を変更した場合、手動で修正しなければならない。
- プレースホルダを置いておき、出力時にファイル名と置換する方法はある。
sample.sh
# !/bin/bash
# @(#)This is sample script.
# @(#)Usage: $0 [-h]
readonly SCRIPTNAME="$(basename "$0")"
Usage () {
what "$0" | sed "s/\$0/$SCRIPTNAME/" 1>&2
}
Notice () {
echo "$SCRIPTNAME": "$*" 1>&2
}
while getopts h OPT
do
case "$OPT" in
h) # @(#) -h: print help
Usage
exit 0
;;
?) # 未定義オプション。getoptsがエラーメッセージを出力する
Usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
pwd # @(#)print current working directory.
$ what ~/bin/sample.sh # コメントがそのまま表示される
/Users/catfist/bin/sample.sh
This is sample script.
Usage: $0 [-h]
-h: print help
print current working directory.
$ sample.sh -h # コメント内の'$0'をファイル名に置換して表示
/Users/catfist/bin/sample.sh
This is sample script.
Usage: sample.sh [-h]
-h: print help
print current working directory.
$ ./sample.sh -z
./sample.sh: illegal option -- z
./sample.sh
This is sample script.
Usage: sample.sh [-h]
-h: print help
print current working directory.
標準エラー出力にリダイレクトすべき
- 上記コードにおいて、
1>&2
によってwhatコマンドの標準出力を標準エラー出力にリダイレクトしている - 標準出力すると説明文がパイプに渡されたりするので、システムメッセージ的なものは全部標準エラー出力にリダイレクトすべき
$ echo "hoge" | sed 's/hoge/fuga/'
fuga
$ echo "hoge" 1>&2 | sed 's/hoge/fuga/'
hoge