2012-06-11 2 views
111

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

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

+0

Не используйте временные файлы. Вместо этого используйте временные каталоги. И не используйте mktemp. См. Здесь почему: http://www.codeproject.com/Articles/15956/Security-Tips-for-Temporary-File-Usage-in-Applicat – ceving

+14

@ceving Эта статья просто неверна, по крайней мере, когда применяется к команде оболочки mktemp (в отличие от вызова библиотеки mktemp). Поскольку mktemp создает сам файл с ограничивающим umask, атака дается только, если атакующий работает под той же учетной записью, что и атакующий ... в этом случае игра уже потеряна. Для получения лучших практик в мире сценариев оболочки см. Http://mywiki.wooledge.org/BashFAQ/062 –

+0

Вы также можете использовать 'tempfile (1)' в системах, которые у него есть. –

ответ

135

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

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

В сценарии, я призываю Mktemp что-то вроде

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

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

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


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

+1

Опция -t устарела: http://www.gnu.org/software/coreutils/manual/html_node/mktemp-invocation.html –

+1

@TeaBee не на OS X. – kojiro

+6

Кажется, наиболее безопасным и наиболее кроссплатформенным способ использования 'mktemp' в комбинации с' basename', как и 'mktemp -dt '$ (basename $ 0). XXXXXXXXXX". Если используется без 'basename', вы можете получить такую ​​ошибку, как этот _mktemp: недопустимый шаблон,' /tmp/MOB-SAN-JOB1-183-ScriptBuildTask-7300464891856663368.sh.XXXXXXXXXX ', содержит каталог separator_. – i4niac

15

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

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

Для получения более подробной информации: man mktemp

26

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

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

> mktemp 
/tmp/tmp.xx4mM3ePQY 
> 
9

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

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


Вы можете использовать следующий подход, чтобы создать временный каталог:

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

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

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

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

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

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

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

+2

не совсем то, что было задано. Тем не менее, это может быть идеальным решением. – jpbochi

+1

@jpbochi Я улучшил ответ, чтобы ответить на вопрос. Дайте мне знать, если это поможет. – kenorb

+0

Это действительно улучшает ответ. Однако мой аванс был уже вашим. Больше не могу голосовать. Одно из моих предложений - объяснить, что '$ {0 ## * /}' и '$$' расширять или ссылаться на некоторую документацию об этом. – jpbochi

Смежные вопросы