Создание временных файлов в bash

Существуют ли объективно лучшие способы создания временных файлов в сценариях bash?

Я обычно называю их тем, что приходит мне на ум, например tempfile-123, так как он будет удален, когда закончится script. Есть ли недостаток в этом, кроме перезаписывания возможного tempfile-123 в текущей папке? Или есть ли преимущество в создании временного файла более тщательным образом?

Ответ 1

Справочная страница mktemp(1) объясняет это довольно хорошо:

Традиционно многие сценарии оболочки принимают название программы с помощью pid как суффикс и использовать его как временное имя файла. Такого рода схемы именования является предсказуемым, и состояние гонки, которое оно создает, легко для злоумышленника победить. Более безопасный, хотя и по-прежнему низкий подход заключается в создании временного каталога с использованием той же схемы именования. В то время как это позволяет гарантировать, что временный файл не будет он по-прежнему допускает простой отказ в обслуживании. Для эти причины предполагают использование mktemp вместо этого.

В script я вызываю mktemp что-то вроде

mydir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename $0).XXXXXXXXXXXX")

который создает временный каталог, в котором я могу работать, и в котором я могу безопасно называть фактические файлы что-то читаемым и полезным.

mktemp не является стандартным, но он существует на многих платформах. "Х", как правило, преобразуются в какую-то случайность, и, скорее, более вероятно, что они будут более случайными; тем не менее, некоторые системы (ящик busybox для одного) ограничивают эту случайность более значительно, чем другие.


Кстати, безопасное создание временных файлов важно не только для сценариев оболочки. Вот почему python имеет tempfile, perl имеет File:: Temp, ruby ​​имеет Tempfile и т.д.

Ответ 2

Да, используйте mktemp.

Он создаст временный файл внутри папки, предназначенной для хранения временных файлов, и это гарантирует вам уникальное имя. Он выводит имя этого файла:

> mktemp
/tmp/tmp.xx4mM3ePQY
>

Ответ 3

Вы можете посмотреть mktemp

Утилита mktemp принимает заданный шаблон имени файла и перезаписывает        чтобы создать уникальное имя файла. Шаблон может быть любым        filename с некоторым количеством добавленных к нему "Xs", например        /tmp/tfile.XXXXXXXXXX. Конечные "Xs" заменяются комбинацией текущего номера процесса и случайных букв.

Подробнее: man mktemp

Ответ 4

Есть ли какое-либо преимущество в создании временного файла более осторожным способом.

Временные файлы обычно создаются во временном каталоге (например, /tmp), где все остальные пользователи и процессы имеют доступ на чтение и запись (любой другой script может создавать новые файлы там). Поэтому script должен быть осторожным при создании файлов, таких как использование с правом разрешения (например, чтение только для владельца, см. help umask), а имя файла должно быть легко угадано (в идеале случайным). В противном случае, если имена файлов не уникальны, это может привести к конфликту с тем же самым script, запущенным несколько раз (например, состояние гонки) или некоторым злоумышленником может либо захватить некоторую конфиденциальную информацию (например, когда разрешения слишком открыты и имя файла легко угадать), либо создать/заменить файл своей версией кода (например, заменить команды или SQL-запросы в зависимости от того, что хранится).


Для создания временного каталога можно использовать следующий подход:

TMPDIR=".${0##*/}-$$" && mkdir -v "$TMPDIR"

или временный файл:

TMPFILE=".${0##*/}-$$" && touch "$TMPFILE"

Однако он все еще предсказуем и не считается безопасным.

Согласно man mktemp, мы можем прочитать:

Традиционно многие сценарии оболочки принимают имя программы с pid как суффикс и используют это как временное имя файла. Такая схема именования предсказуема, и состояние гонки, которое она создает, легко победить злоумышленнику.

Чтобы было безопасно, рекомендуется использовать команду mktemp для создания уникального временного файла или каталога (-d).