ラベル ash の投稿を表示しています。 すべての投稿を表示
ラベル ash の投稿を表示しています。 すべての投稿を表示

2012年2月21日火曜日

getoptsとシェルの選択


シェルついでにgetopsの話。getoptsを使うと、こんな感じでオプションのパーサを楽に書ける。
opt_a=
opt_b=
opt_c=
opt_d=
while getopts ‘abc:d:’ opt; do
  case $opt in
    a|b)
      eval “opt_$opt=1”;;
    c|d)
      eval “opt_$opt=’$OPTARG’”;;
  esac
done
shift `expr $OPTIND - 1`
上の例だと-aと-bが引数なし、-cと-dが引数ありのオプション。-abc ARGのように、複数のオプションをまとめて指定しても、きちんと解釈してくれる。引数ありのオプションは、-d ARGでも-dARGでもOK。
そんな便利なgetoptsの最大の弱点は、標準で備わっている保証がないこと。ただbashならgetoptsはbuilt-in化されているので、多少の可搬性を犠牲にしてでもgetoptsを使いたいときはshebangで
#!/bin/bash
と明示している。
ashでもbuilt-in化できることはできるが、ビルド時に無効にもできるので、ashならgetoptsが使えるという保証はできない。PCならともかく、組み込みだと切られているケースもあるかも。

2012年2月20日月曜日

Bシェル系の拡張変数展開とシェル選択



アンチcshとしては、Bシェル系でもcshの${var:e}みたいなことを条件付きでできることを示さざるを得ない。
  • ${var#pattern}は、varの先頭からpatternに最短一致した部分を取り除いた文字列
  • ${var##pattern}は、varの先頭からpatternに最長一致した部分を取り除いた文字列
  • ${var%pattern}は、varの末尾からpatternに最短一致した部分を取り除いた文字列
  • ${var%%pattern}は、varの末尾からpatternに最長一致した部分を取り除いた文字列

例えば

% var=foo/bar/baz.tar.gz
% echo ${var#*/}
bar/baz/tar.gz
% echo ${var##*/}
baz.tar.gz
% echo ${var%.*}
foo/bar/baz.tar
% echo ${var%%.*}
foo/bar/baz
% watch_out=foo.bar/baz.tar.gz
% echo ${watch_out%%.*}
foo
こんな感じ。
これはてっきりbashの拡張機能だと思っていたので、多少の可搬性を犠牲にしてでも楽をしたいときのみshebangで

#!/bin/bash
と指定して使っていた。が、実は割と初期のashで既に拡張されていたらしい。
http://www.in-ulm.de/~mascheck/various/ash/
手元のash/dashでは確かに#, %を使えた。ashは拡張されていないイメージだったので、意外。
まあashでも通ると言うだけで、Solarisの/bin/shとかだとやっぱり駄目なので、この機能を使うときはbashという選択で、引き続き問題ないかな。