拡張 POSIX シェルスクリプト Advent Calendar 2013、7日目の記事です。
昨日のネタの続きで
mktemp
(1) もどきをシェルスクリプトで実装してみました。
mktemp
コマンドの仕様
mktemp
の主な仕様をおさらいしましょう。
/tmp/tmp.<ランダム文字列>
という名前のファイルを作成する。- 必ず新規のファイルとなる。既存のファイルを絶対に上書きしない。
- 競合の回避。
- シンボリックリンク攻撃の回避。
- ファイルのモードは必ず 0700 になる。
- ファイル内容漏洩の回避。
まずは、これらをシェルスクリプトで実現する方法を紹介します。
/tmp/tmp.<ランダム文字列>
という名前のファイルを作成
bash, ksh, zsh なら $RANDOM
で乱数が得られるので、
この仕様に即したファイル名を作るのは簡単です。
$ bash -c 'seeds=(0 1 2 3 4 5 6 7 8 9); echo "${seeds[$RANDOM % ${#seeds[@]}]}"'
…seeds内の一文字がランダムに表示される…
既存ファイルの上書きを避けた新規ファイルの作成
ファイルの作成は : >ファイル名
が定番ですね。
既存ファイルの上書きを避けるには、
リダイレクト時のファイル上書きを拒否するシェルオプション noclobber
が利用できます。
$ bash -c 'set -o noclobber; ls -l file; : >file; ls -l file; : >file'
file: ファイルもディレクトリもありません。
-rw-rw-r-- 1 fumiyas users 0 12月 6日 20:28 file
bash: file: cannot overwrite existing file
noclobber
を有効にした後、リダイレクトでファイルの作成を試みて、
失敗したら別の名前で再試行…を成功するまで繰り返す実装にすればよいです。
ちなみに noclobber
を利用せずに「(1)ファイルの作成前にファイルの存在を検査し、
(2)存在しなかったらファイルを作成する」という実装にした場合、
(1) と (2) の間に別プロセスがファイルを作成する余地があるため、
安全ではありません。
noclobber
がどのように既存ファイルの上書きを回避しているか興味のある方は、
open
(2) システムコールのマニュアル記載の O_EXCL
フラグを参照してください。
O_EXCL
によりファイルの存在有無とファイル作成がカーネル内部で不可分で行なわれるため、
ほかのプロセスと競合することはありません。
新規ファイルのモードを 0700 にする
これは簡単ですね。ファイル作成時の umask
値を 0077
に設定するだけです。
$ bash -c 'umask; : >file1; ls -l file1; umask 0077; umask; : >file2; ls -l file2'
0002
-rw-rw-r-- 1 fumiyas users 0 12月 6 20:32 file1
0077
-rw------- 1 fumiyas users 0 12月 6 20:32 file2
「(1) umask
値を気にせずにファイルを作成した後に (2) モードを 0700
に変更する」
という実装にした場合、(1) と (2) の間に別プロセスがファイルを開く余地があるため、
安全ではありません。
ファイルのモードをいくら制限しても、オープン済みのプロセスに対しては何ら抑止効果はありません。
mktemp.bash
の実装例
以上を元に mktemp.bash
を実装しました。
スクリプト名は *.bash
ですが、いつものように ksh, zsh でも動きます。
zsh はある条件で妙なエラーメッセージが出ますが、面倒なので放置しています
(基本的な動作は問題ありません)。
ところで、12月25日はクリスマスな上に、
OSS 界隈で地味に活躍されているふみやすさんの誕生日ですね!
っ http://www.amazon.co.jp/registry/wishlist/27M7TV8CEEF6G?sort=priority
逆に、あなたの書いた OSS や Blog や Advent Calendar が気に入ったら何か送りたく なってしまうかもしれないので、プロフィールや Web サイトに あなたの Amazon 欲しいものリストの URL を貼っておいてくださいね!
私が勤める OSSTech っていう某弊社で社員募集しているようです。 人材紹介会社を介さなければ、入社後に 20万円のボーナス! 「ふみやすっていう人に紹介された」と言ってもらえると私にもボーナス!! → https://www.osstech.co.jp/recruit/
よろしければ、これまで参加した/参加予定のほかの Advent Calendar もどうぞ。
- Ansible Advent Calendar 2023
- シェル芸 Advent Calendar 2023
- 闇の魔術に対する防衛術 Advent Calendar 2023
- Ansible Advent Calendar 2023
- Ansible Advent Calendar 2020
- DNS温泉 Advent Calendar 2019
- OSSTech Advent Calendar 2019
- Ansible Advent Calendar 2018
- OSSTech Advent Calendar 2018
- Debian/Ubuntu Advent Calendar 2017
- Linux Advent Calendar 2017
- Shell Script Advent Calendar 2017
- Shell Script Advent Calendar 2016
- OpenLDAP と仲間たち Advent Calendar 2015
- Postfix Advent Calendar 2014
- 拡張 POSIX シェルスクリプト Advent Calendar 2013