一時ファイルの作成と削除(シェルプログラミング)
一時ファイルの作成
tmpfile=$(mktemp 一時ファイルテンプレート名)
- mktemp(1) コマンドは以下の条件を満たすユニークなファイル(or ディレクトリ)を作成および、そのファイル(or ディレクトリ)名を得ることができます。
- ファイル(ディレクトリ)作成時にレースコンディションを起こしません。
- シンボリックリンクを含む、既ファイル(ディレクトリ)名ではありません。
- ファイル(ディレクトリ)名がユニークであること(後述)。
- umask の設定に寄らず、デフォルトパーミッションは 0600(0700)になります。
- シェルプログラミングレベルで、もっともセキュアな手順で作られた一時ファイル(ディレクトリ)であることが保証されています。
- とは言え、究極的にセキュア、というわけではありません。
- 一時ファイルは以下のルールにより作成されます。
- 「X」という文字は置き換え対象となります(テンプレート)。
- 「X」は英数字(大文字・小文字・数字)の62文字からなるランダムに選択された文字です。
- よって連続した「X」の数を増やせば増やすほど、ユニーク性が高まります(衝突確率が減ります)。
一時ファイルの削除
rm -f "$tmpfile"
実際にはこれでは不十分で、全ての終了前ルートに仕込む必要があります。
異常時の一時ファイルの削除
trap 'rm -f "$tmpfile"' HUP INT QUIT TERM USR1 USR2
- 異常時といっても典型的なシグナルを受けての削除処理です。
- エラーハンドリングをしなくて良いわけではありません。エラーハンドリングはちゃんとすること。
終了時に一時ファイルの削除
trap 'rm -f "$tmpfile"' EXIT
- 「trap」には「終了時」を意味する疑似シグナル「EXIT」が使用可能です。
- これによりあらゆる状況での終了時に削除してくれます(嘘)。
そのあたりまとめて削除する手順
- trap EXIT は通常終了する範囲では仕事してくれるけど、シグナル受信時は仕事してくれない。
- trap SIGNAL では仕事してくれるけど、今度はシグナル処理後の EXIT 「でも」仕事してしまう。
- そのあたり手間を含めて「終了時処理」というイレギュラーなフローは関数にしてまとめてしまうこと。
atexit () { trap - EXIT rm -f "$tmpfile" } trap atexit EXIT HUP INT QUIT TERM USR1 USR2