メモの日々


2011年08月15日(月) [長年日記]

  • シェルスクリプトを書いた。bashの機能は遠慮なく使う。知ったことをいくつかメモ。

[shell][unix][howto] シェルスクリプトで一時ファイルを作成し、削除する

作成

シェルスクリプトで一時ファイルを作成するのに、プロセスIDを使用するのはセキュアでないので避けたい。

それより、mktempコマンドを使うのがよさそう。このコマンドは適当な名前で空のファイルまたはディレクトリを作成し、そのファイル名を出力してくれる。使うのも簡単だし、手元のLinuxでは標準でインストールされていた。

削除

一時ファイルは、シェルスクリプトが終了たときに自動で削除されて欲しい。これはbashのtrapコマンドで実現できる。「sigspec が EXIT (0) であれば、シェルの終了時にコマンド arg が実行されます。」ということなので、

trap "rm -fv $tmpfile" EXIT

のようにしておけば自動的に $tmpfile は削除される。SIGTERMなどのシグナル受信時にもちゃんと削除される。ただし、SIGKILLシグナル受信時には削除されないようだ。これは仕方ないかな。

複数の一時ファイル

一時ファイルを複数使うなら、mktempを何度も呼ぶより、mktempでディレクトリを作成してその中にファイルを自由に作る方が、ファイルの削除が簡単に済んで便利。

tmpdir=`mktemp -d`
trap "rm -rfv $tmpdir" EXIT

[shell][unix][howto] シェルスクリプトで連番の生成

連番はseqコマンドで生成できる。このコマンドには色々な機能があって便利なので活用すべし。

が、seqコマンドを使わなくても、手元のbashは {x..y} と書けば連番を展開してくれた。

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10

zshでも同じように動いた。zshだと {00..10} とすることで、seqの -w オプションと同じようなゼロ埋めもできた。手元のbash(version 3.00.15)ではゼロ埋めができなかったが、もっと新しいバージョンだとできるらしい。

また、bashだと文字の連番も生成できたが、これはzshではできなかった。

$ echo {A..Z}
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

{x..y}の展開機能は、JMにあるman bashの日本語訳にはなかった。本家のマニュアルには次のようにある。

A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters, and incr, an optional increment, is an integer.

ここにある ..incr というオプションも手元の古いbashでは動かなかった。

[shell][howto] シェルスクリプトで多重ループを抜ける

シェルスクリプトで多重ループを抜けるのにどう書けばいいのか知らなかったけど、「break 2」とすれば2レベル分のループを抜けられると知った。breakは組み込みコマンドなのか。

なお、引数なしの break は break 1 と同じみたい。