← Весь справочник

mktemp

Безопасное создание временных файлов и каталогов с уникальными именами

mktemp создаёт временный файл (или с -d — каталог) с непредсказуемым уникальным именем и печатает путь к нему. Файл создаётся с правами 600, каталог — 700: доступ только у владельца. Путь сохраняют в переменную, а удаление поручают trap. В песочнице — GNU coreutils 9.4.

Синтаксис

mktemp [опции] [шаблон]

Без шаблона: $TMPDIR/tmp.XXXXXXXXXX (если TMPDIR не задан — /tmp). Каждая X в конце шаблона заменяется случайной буквой или цифрой; их должно быть не меньше трёх.

Опции

ОпцияЧто делает
-dсоздать каталог, а не файл
-p каталогсоздать в этом каталоге; шаблон — просто имя. -p "" или -p без значения — $TMPDIR, иначе /tmp
--tmpdir[=каталог]длинная форма -p
-tшаблон — только имя; каталог — $TMPDIR, если задан (он важнее -p!), иначе из -p, иначе /tmp. Устаревшая форма, вместо неё --tmpdir
--suffix=.extдобавить суффикс после X: tmp.Ab3dE.conf
-uничего не создавать, только напечатать имя (небезопасно: имя может успеть занять кто-то другой)
-qне печатать ошибку, если создать не удалось (код возврата всё равно 1)

Куда попадёт файл

ВызовГде создаётся
mktemp$TMPDIR или /tmp
mktemp app.XXXXXXв текущем каталоге: шаблон с относительным путём
mktemp /var/tmp/app.XXXXXXточно по пути из шаблона
mktemp -p /var/tmp/var/tmp/tmp.XXXXXXXXXX — -p важнее TMPDIR
mktemp -t app.XXXX$TMPDIR/app.XXXX или /tmp/app.XXXX
mktemp --tmpdir app.XXXXXX.json$TMPDIR или /tmp, суффикс после X тоже допустим

Уборка через trap

#!/bin/bash
set -euo pipefail

tmp=$(mktemp -d)
trap 'rm -rf -- "$tmp"' EXIT     # сработает при любом выходе

curl -fsSL https://example.com/data.json -o "$tmp/data.json"
jq '.items' "$tmp/data.json"

EXIT-ловушка в bash срабатывает при обычном завершении, при выходе по set -e и при завершении по SIGTERM/SIGINT. Не сработает только при SIGKILL (kill -9) — тут не поможет ничто.

Примеры

# временный файл
tmp=$(mktemp)
sort data.txt > "$tmp" && mv "$tmp" data.txt

# временный каталог
work=$(mktemp -d)

# понятный префикс — легче найти в /tmp, если что-то осталось
mktemp -t backup.XXXXXX

# с расширением — некоторые программы смотрят на него
mktemp --suffix=.json

# рядом с целевым файлом (та же ФС) — для атомарной замены через mv
tmp=$(mktemp -p /etc/myapp app.conf.XXXXXX)

# проверить, что создание удалось
tmp=$(mktemp) || { echo 'не удалось создать временный файл' >&2; exit 1; }

Подводные камни

  • Не придумывай имена сам. /tmp/myscript.$$ предсказуем: другой пользователь может заранее создать ссылку с таким именем, и скрипт запишет данные туда, куда она ведёт. mktemp создаёт файл атомарно и с правами 600.
  • Мало X: mktemp app.XX — «too few X's in template». Нужно минимум три, лучше шесть и больше.
  • Шаблон без пути создаётся в текущем каталоге, а не в /tmp. Хочешь в /tmp — -t, -p или полный путь.
  • Права 600. Если временный файл потом станет постоянным (через mv), у него останутся права 600 — поменяй их chmod.
  • Без trap мусор копится: скрипт упал посередине — файл остался в /tmp. Ставь trap сразу после mktemp.
  • Одинарные кавычки в trap. В trap 'rm -rf -- "$tmp"' EXIT переменная раскроется при срабатывании. С двойными кавычками она подставится сразу — работает, но ломается, если в пути есть пробелы или кавычки.

См. также

kill · set · exit-codes · mv · rm · umask · variables