そんな経験はありませんか?
一時ファイルの名前を固定していると、並列実行時の上書き・競合リスクがあります。
mktemp コマンドを使えば、重複しないユニークなファイル名を自動生成できます。
この記事では、mktemp コマンドの基本的な使い方から、シェルスクリプトでの安全な一時ファイル管理、自動削除(trap との組み合わせ)まで解説します。
RHEL 9.4 / Ubuntu 24.04 LTS で動作確認済みです。
この記事のポイント
・mktemp でユニークな一時ファイルを自動生成できる
・-d オプションで一時ディレクトリも作れる
・trap と組み合わせてスクリプト終了時に自動削除する
・並列実行時の競合・上書き事故を根本から防げる
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜ一時ファイルの名前を固定してはいけないのか
シェルスクリプト初心者がよくやるのが、次のような固定ファイル名の使い方です。# NG例:固定ファイル名は並列実行で競合する TMP=/tmp/myapp_tmp.txt echo "処理結果" > $TMP
cronやバッチ処理で複数起動する環境では、必ずこの問題に直面します。
さらに深刻なのがシンボリックリンク攻撃(Symlink Attack)です。
攻撃者があらかじめ /tmp/myapp_tmp.txt を重要ファイルへのシンボリックリンクとして作成しておくと、スクリプトがそのファイルに書き込んだ瞬間に重要ファイルが上書きされます。
mktemp はこれらの問題を1行で解決します。
mktempコマンドの基本的な使い方
1. 一時ファイルを作成する
mktempの最もシンプルな使い方です。$ mktemp /tmp/tmp.abc123XYZ
生成されたファイルは空の状態で既に作成されているため、すぐに書き込めます。
2. テンプレートで名前のパターンを指定する
ファイル名のプレフィックスをわかりやすくしたい場合は、テンプレートを指定します。テンプレートの末尾には必ず「X」を6文字以上並べます。
# myapp_ というプレフィックスで一時ファイルを作成する $ mktemp /tmp/myapp_XXXXXX /tmp/myapp_K7mN2p # スクリプト名を含めるとデバッグ時にわかりやすい $ mktemp /tmp/backup_XXXXXXXX /tmp/backup_4fGh8kLq
6文字未満だと警告が出るディストリビューションもあるため、6文字以上のXを使うのが安全です。
3. 一時ディレクトリを作成する(-d オプション)
複数の一時ファイルをまとめて扱いたい場合は、一時ディレクトリを作成します。# -d オプションで一時ディレクトリを作成する $ mktemp -d /tmp/tmp.fQ3sBxKmNv # テンプレートを指定することもできる $ mktemp -d /tmp/work_XXXXXX /tmp/work_R2xPqM # 作成されたか確認する $ ls -la /tmp/work_R2xPqM total 0 drwx------ 2 tomohiro tomohiro 40 May 9 10:35 . drwxrwxrwt 12 root root 300 May 9 10:35 ..
セキュリティ上、他のユーザーからはアクセスできない状態で作成されます。
シェルスクリプトでの実践的な使い方
1. 基本パターン:変数に格納して使う
スクリプト内でmktempを使う基本的なパターンです。#!/bin/bash # 一時ファイルを作成して変数に格納する TMPFILE=$(mktemp /tmp/myapp_XXXXXX) # 処理内容を書き込む echo "処理データ1" >> "$TMPFILE" echo "処理データ2" >> "$TMPFILE" # ファイルの内容を確認する cat "$TMPFILE" # 使い終わったら削除する rm -f "$TMPFILE"
2. trap で自動削除する(推奨パターン)
スクリプトが途中でエラー終了したときも、必ず一時ファイルを削除するのが実務の鉄則です。trap コマンドと組み合わせることで、正常終了・異常終了どちらの場合でも自動削除できます。
#!/bin/bash set -e # 一時ファイルを作成する TMPFILE=$(mktemp /tmp/report_XXXXXX) # EXIT シグナルで必ず削除する # スクリプトが正常終了・エラー終了どちらでも実行される trap 'rm -f "$TMPFILE"' EXIT # 何らかの処理 ls -la /var/log/ > "$TMPFILE" grep "error" "$TMPFILE" || true echo "処理完了: $TMPFILE の内容を確認しました" # スクリプト終了時に trap が実行され TMPFILE が自動削除される
「rm を書き忘れた」「エラーで途中終了した」という状況でも /tmp が汚染されません。
Linux 基本コマンドの解説でも触れていますが、/tmp の残骸は予期しないディスク不足の原因になります。
3. 一時ディレクトリを使った複数ファイル管理
複数の中間ファイルを使う処理では、一時ディレクトリをまとめて削除する方が安全です。#!/bin/bash set -e # 一時ディレクトリを作成する TMPDIR=$(mktemp -d /tmp/process_XXXXXX) # EXIT 時に一時ディレクトリごと削除する trap 'rm -rf "$TMPDIR"' EXIT # 一時ディレクトリ内で複数ファイルを扱う cat /var/log/messages | grep "error" > "$TMPDIR/errors.txt" cat /var/log/messages | grep "warn" > "$TMPDIR/warnings.txt" wc -l "$TMPDIR/errors.txt" "$TMPDIR/warnings.txt" echo "エラー数と警告数を集計しました"
rm -rf "$TMPDIR" で一括削除できるため、ファイルごとにrmを書く必要もありません。
応用・実務Tips
4. 並列処理での安全な一時ファイル使用
cronやバッチ処理で同じスクリプトが並列実行される環境では、mktempは必須です。#!/bin/bash # バックアップスクリプト(並列実行対応版) LOCKFILE=$(mktemp /tmp/backup_lock_XXXXXX) TMPOUT=$(mktemp /tmp/backup_out_XXXXXX) trap 'rm -f "$LOCKFILE" "$TMPOUT"' EXIT # /tmp は全ユーザーが書き込める領域なので # mktemp で生成したパスは他プロセスと衝突しない echo "バックアップ開始: $$" > "$LOCKFILE" tar -czf /backup/data_$(date +%Y%m%d_%H%M%S).tar.gz /var/data/ 2> "$TMPOUT" if [ -s "$TMPOUT" ]; then echo "警告が発生しました:" cat "$TMPOUT" fi
5. mktemp のパスを安全に扱うためのポイント
・ダブルクォートで囲む:スペースを含むパスでも正しく動作させるため、変数展開は必ず "$TMPFILE" と書く・TMPDIR 変数:環境変数 TMPDIR が設定されている場合、mktemp はその場所に作成する。明示的にパスを指定すれば TMPDIR に依存しない
・-p オプション(GNU版):`mktemp -p /var/tmp XXXXXX` のように、作成先ディレクトリを -p オプションで指定できる
・macOS との互換性:macOS の mktemp はBSD版で動作が異なる場合がある。クロスプラットフォームスクリプトでは `mktemp /tmp/XXXXXX` の形式が安全
6. 実サーバーでのデバッグ確認例
実際のサーバーで mktemp を使ったスクリプトのデバッグをしたときの出力例です。[tomohiro@web01 ~]$ cat test_mktemp.sh #!/bin/bash TMPFILE=$(mktemp /tmp/test_XXXXXX) trap 'echo "削除: $TMPFILE"; rm -f "$TMPFILE"' EXIT echo "作成されたファイル: $TMPFILE" ls -la "$TMPFILE" [tomohiro@web01 ~]$ bash test_mktemp.sh 作成されたファイル: /tmp/test_Kx8mNpQr -rw------- 1 tomohiro tomohiro 0 May 9 10:42 /tmp/test_Kx8mNpQr 削除: /tmp/test_Kx8mNpQr [tomohiro@web01 ~]$ ls /tmp/test_* ls: cannot access '/tmp/test_*': No such file or directory
trap による自動削除が正しく機能しています。
トラブルシュート・エラー対処
「mktemp: too few X's in template」が出た場合
テンプレートの末尾の「X」が少ない場合に発生します。# NG:X が 3 文字では警告が出る場合がある $ mktemp /tmp/tmp_XXX mktemp: too few X's in template '/tmp/tmp_XXX' # OK:末尾に X を 6 文字以上 $ mktemp /tmp/tmp_XXXXXX /tmp/tmp_abc123
「mktemp: failed to create file」が出た場合
作成先ディレクトリが存在しない、または書き込み権限がない場合に発生します。# 存在しないディレクトリを指定した場合 $ mktemp /tmp/nonexistent/tmp_XXXXXX mktemp: failed to create file via template '/tmp/nonexistent/tmp_XXXXXX': No such file or directory # /tmp 自体の権限を確認する $ ls -la /tmp drwxrwxrwt 12 root root 300 May 9 10:35 /tmp # ↑ スティッキービットが設定されていれば正常 # /tmp への書き込み権限がない場合(稀) $ df -h /tmp Filesystem Size Used Avail Use% Mounted on tmpfs 512M 450M 62M 88% /tmp # ディスク使用率が高い場合は不要ファイルを削除する
スクリプトが kill -9 で強制終了されたとき
trap は kill -9(SIGKILL)では実行されません。定期的に /tmp を掃除するために、cron で古い一時ファイルを削除する運用を組み合わせるのが実務上の対処です。
# crontab に追記:24時間以上前の /tmp/myapp_* を削除する # ファイル名のプレフィックスで絞り込んで削除する 0 3 * * * find /tmp -maxdepth 1 -name "myapp_*" -mtime +1 -delete
本記事のまとめ
mktemp コマンドの重要なポイントを一覧にまとめます。| やりたいこと | コマンド |
|---|---|
| 一時ファイルを作成する | mktemp /tmp/myapp_XXXXXX |
| 一時ディレクトリを作成する | mktemp -d /tmp/work_XXXXXX |
| 変数に格納して使う | TMPFILE=$(mktemp /tmp/app_XXXXXX) |
| スクリプト終了時に自動削除する | trap 'rm -f "$TMPFILE"' EXIT |
| 一時ディレクトリを自動削除する | trap 'rm -rf "$TMPDIR"' EXIT |
| 作成先ディレクトリを指定する(GNU版) | mktemp -p /var/tmp XXXXXX |
この1つの習慣で、並列実行の競合・シンボリックリンク攻撃・/tmp の汚染という3つのリスクを同時に排除できます。
シェルスクリプトの知識、現場で使える形になっていますか?
mktemp や trap による安全なスクリプト設計はサーバー管理の基礎です。SSHの鍵管理、ファイアウォール設定、ユーザー権限管理——これらを体系的に理解していないと、いざというときに手が止まります。
コマンドのコピペでその場をしのぐのではなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます