getopt

なんとなく http://openlab.dino.co.jp/2007/10/05/17461999.html を読んで getopt について最近気づいたことをメモ。以下、パッケージ名はdebian限定。

とくに理由はないんですが getopt って getopt(3) のイメージが強くて、 php で書くときはちゃんと getopt するくせに、シェルスクリプトだと $1 を直接使っちゃったりしてました。

ところがふと getopt(1) (コマンドラインから動くgetoptコマンド) ってのが util-linux に入ってることに気づいて、かなり使えることが分かった。ある程度複雑なことするならラッパースクリプトを他の言語で書いちゃったほうが早いのは相変わらずだけど、それなりに便利。

たとえば日付を [-d|--date=] で受け取りたいならこんなかんじ。 eval は man 1 getopt するかググれば詳しいことがどっかに書いてあります。 yesterday ってのは default 値ね。

args=`getopt -o d: -l date: -- "$@"`
if [ $? != 0 ]; then
	exit 1
fi
eval set -- "$args"

date=`date +%Y%m%d -d yesterday`
while true; do
	case "$1" in
	-d|--date)
		date=`date +%Y%m%d -d "$2"`
		shift 2
		;;
	--)
		shift
		break
		;;
	*)
		echo "unknown params: $1" >&2
		exit 1
		;;
	esac
done

echo $date

まあ bash なら getopts 使えばいいじゃんって話もあるんですけどね。

それで

"--" って、ヒストリからオプションを1つ追加したいときとかに、-- の後ろにつけててよくハマるので、あんま好きじゃないです。grep で -hoge を探したいなら

$ grep "\-hoge" *.php --color
$ grep \\-hoge *.php --color

というふうに頑張ってクオート(というかエスケープ)してもいけます。

grep.c の prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv); 読んでてどうでもいいことに気づいた。

$ export GREP_OPTIONS="--"

なんてやられたら悲惨。「 -- の恐怖」ってかんじです。