2015年7月8日水曜日

Posted by mattintosh | File under : , , , , ,
最初の方に書いておくべきでしたが変数などのお話です。

「変数とはなにか?」についてはここでは詳しくお話しません(ウェブ上にたくさん情報があるので検索してみてください)。

変数の型

C 言語などでは変数には「型」を指定する必要がありますが、bash の変数は何でも入ります(nul は入らなかったと思いますが)。

そんな何でもアリな bash の変数ですが、declare を使うことで整数値として宣言することができます。 declare -i で宣言しているものは英字を入れても 0 になります(※記号などを代入しようとするとエラーになります)。

変数展開時の {} って必要?

これまでのスクリプトではすべて ${PATH} のように {}(ブレース⁄brace)を記述してきましたが、$PATH と書いても問題はありません。私はスクリプトではできるだ書くようにしていますが、対話モードでは必要なときだけつけています。

ブレースが必要になるパターンをいくつかお話します。

変数名の区切りとして

{} が必要なとき」というのは下の実行結果を見てみてください。 変数名にブレースがない場合は「$ から変数名として使える文字が終わるところまで」が変数名になります。3行目と5行目を見比べてみるとわかりますが、ブレースを使うことで「どこからどこまでが変数名なのか?」を指定することができます。

7行目のような書き方でも展開はできますがあまりこういった書き方はしません(私はですが)。

8行目ではブレースなしでも $BASH が正しく展開されていますが、$BASH.VERSION という変数は存在しない(というか . があるので宣言できない)ので $BASH という変数と .VERSION という文字列として認識されます。

よくある間違いは変数と _ を使って文字を連結する場合です。なぜ _ の方だけ $BASH 部分が展開されていないかはもうわかりますね?

配列の展開のために

BASH_VERSINFO は bash のバージョン情報が入った配列変数です。 BASH_VERSINFO をブレースありとなしで出力してみます。 ブレースなしの方は $BASH_VERSINFO という変数と [〈インデックス〉] という文字列として認識されます。 今度は for を使ってインデックスを変数から展開します。 先程と同じくブレースなしの方は正しく展開されていません。また、ブレース内の [〈変数〉]$ を付けなくても展開されていますが、ブレースなしの方はそちらも展開されていません。 配列変数を展開するにはブレースが必要になります(※0番目の要素は除く)。$BASH_VERSINFO[0] と書いたものは ${BASH_VERSINFO}[0] と書いたときと同じ認識になってるんですね。

置換展開のため

bash を含め、いくつかのシェルではブレースを使った変数展開の際に、特殊な展開を行うことができます。 シェルのコマンドには Ruby などにある拡張子だけを取り出す extname() のようなものがありません(知らないだけかもしれませんが)。ですが、上記のような置換展開を使うことで cut や sed のようなコマンドに頼らず拡張子だけを取り出すことができます。
ブレースが必要になるパターンというのはおわかりいただけたでしょうか?私は「後で書くくらいなら最初から書いておく」タイプなので書いてますが、先に述べたようにブレースなしでも動くものは動きます。

変数に関することはまだまだたくさんあるのですが、長くなってしまったので今回はこの辺で終わりにしたいと思います。

最後にお遊びスクリプトとして画像ファイルを一括で JPEG に変換するスクリプトを紹介します。convert は ImageMagick に含まれている画像変換プログラムです。

case を併用することで拡張子がついているかどうかをより正確に判断できるようになります。

休みの日にだらだらと書いてしまったので説明の順序がごちゃごちゃになってしまいました。ごめんなさい。

ではまたそのうちお会いしましょう(・∀・)ノシ