6と7のリビジョン間の差分
2019-07-09 11:59:43時点のリビジョン6
サイズ: 3280
コメント:
2019-07-09 11:59:55時点のリビジョン7
サイズ: 3281
コメント:
削除された箇所はこのように表示されます。 追加された箇所はこのように表示されます。
行 56: 行 56:
    rm -f "$tmpfile     rm -f "$tmpfile"

一時ファイルの作成と削除(シェルプログラミング)

一時ファイルの作成

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

参考文献

シェル/MakeAndRemoveTemporaryFile (最終更新日時 2019-07-09 11:59:55 更新者 NorikatsuShigemura)