Должны ли временные файлы быть сохранены в / tmp или текущем рабочем каталоге?

76

У меня есть программа, которая должна создавать временные файлы. Написано для кластерных машин.

Если я сохранял эти файлы во системном временном каталоге (например:) /tmp, некоторые пользователи жаловались на сбой программы, поскольку у них не было надлежащего доступа к / tmp. Но если я сохранил эти файлы в рабочем каталоге, эти пользователи также пожаловались, что не хотят видеть эти загадочные файлы.

Какой из них лучше? Должен ли я настаивать на том, что сохранение /tmpявляется правильным подходом, и защищать любой сбой как «работающий по назначению» (т. Е. Спрашивать у своего администратора правильное разрешение / доступ)?

SmallChess
источник
3
проверьте, есть ли у программы доступ и, если нет, найдите другую временную директорию
ratchet freak
24
Если ваш админ испортил права доступа, он обязательно должен это исправить. Что бы вы сделали, если бы ваш администратор забыл добавить права на выполнение в вашу программу?
Док Браун
7
Вы не найдете / tmp в большинстве систем Windows, но есть вызов ОС, который скажет вам, куда поместить временные файлы.
Ян
28
Если у некоторых людей нет доступа к /tmpUnix-подобной системе, это неверно настроено. Суперпользователь должен сделать что-то вроде chmod 1777 /tmp.
Musiphil
12
Помните, что $ TMPDIR может указывать на путь, отличный от того /tmp/, который вы должны использовать вместо этого. Посмотрите ответы на некоторые вопросы;)
marcelm

Ответы:

141

Временные файлы должны храниться во временном каталоге операционной системы по нескольким причинам:

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

  • Большинство программ резервного копирования знает, какие каталоги содержат временные файлы, и пропускает их. Если вы используете текущий каталог, это может оказать существенное влияние на размер инкрементных резервных копий, если резервные копии выполняются часто.

  • Временный каталог может находиться на другом диске или в ОЗУ, что делает доступ для чтения и записи намного, намного быстрее .

  • Временные файлы часто удаляются во время перезагрузки (если они находятся на виртуальном диске, они просто теряются). Это снижает риск бесконечного роста, если ваше приложение не всегда правильно удаляет временные файлы (например, после сбоя).

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

  • Длина пути может быть слишком большой на некоторых платформах. Например, в Windows ограничения пути для некоторых API, каркасов и приложений ужасны , что означает, что вы можете легко достичь такого предела, если текущий каталог уже находится глубоко в древовидной иерархии и имена ваших временных файлов слишком длинные.

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

Что касается ошибок в доступе, убедитесь, что операционная система создала временный файл для вас. Операционная система может, например, знать, что для данного пользователя используется каталог, отличный от /tmpили C:\Windows\tempдолжен быть; таким образом, при непосредственном доступе к этим каталогам вы действительно можете столкнуться с ошибкой в ​​доступе.

Если вы получаете отказ в доступе даже при использовании вызова операционной системы, это просто означает, что машина была плохо настроена; это уже объяснил Blrfl . Системный администратор должен настроить машину; вам не нужно менять приложение.

Создание временных файлов является простым на многих языках. Несколько примеров:

  • Bash:

    # The next line will create a temporary file and return its path.
    path="$(mktemp)"
    echo "Hello, World!" > "$path"
    
  • Python:

    import tempfile
    
    # Creates a file and returns a tuple containing both the handle and the path.
    handle, path = tempfile.mkstemp()
    with open(handle, "w") as f:
        f.write("Hello, World!");
    
  • C #:

    // Creates a file and returns the path.
    var path = Path.GetTempFileName();
    File.WriteAllText(path, "Hello, World!");
    
  • PHP:

    # Creates a file and returns the handle.
    $temp = tmpfile();
    fwrite($temp, "Hello, World!");
    fclose($temp);
    
  • Рубин:

    require "tempfile"
    
    # Creates a file and returns the file object.
    file = Tempfile.new ""
    file << "Hello, World!"
    file.close
    

Обратите внимание, что в некоторых случаях, например в PHP и Ruby, файл удаляется при закрытии дескриптора. Это дополнительное преимущество использования библиотек, связанных с языком / структурой.

Арсений Мурзенко
источник
2
Что вы подразумеваете под «убедитесь, что вы позволили операционной системе создать временный файл для вас». Таким образом, вместо того, чтобы, например, fopen("/tmp/mytmpfile", "w");я должен сделать какой-то системный вызов для обработки временных файлов?
Симон
30
@gurka: Вы должны звонить, tmpfile(3)чтобы сгенерировать ваши временные файлы, или, по крайней мере, звонить, mktemp(3)чтобы создавать имена файлов.
TMN
3
@ TMN: это просто библиотечные функции, которые выполняются в пользовательском пространстве, и у них нет никакого волшебства, чтобы обойти ошибку разрешения, выданную операционной системой.
Musiphil
25
@musiphil И tmpfile, и mktemp используют внешние переменные для определения пути для временных файлов. Возможно, они были настроены так, чтобы указывать на каталог, отличный от / tmp /, возможно, на каталог пользователя. Попытка создать имя файла вручную в / tmp / может потерпеть неудачу, в то время как tmpfile и mktemp вернут правильные пути.
труба
2
@musiphil: я никогда не говорил, что они решат проблему с разрешениями, я отвечал на его вопрос об использовании системных вызовов для создания файлов.
TMN
33

Должен ли я настаивать на том, чтобы сохранение в / tmp было правильным подходом, и защищать от любых сбоев как «работающие по назначению» (т. Е. Спрашивайте у администратора правильные права доступа)?

Для этого есть стандарты, и лучшее, что вы можете сделать, это соответствовать им.

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

  • stdio.hЗаголовок C может дополнительно включать P_tmpdirмакрос, который называет временный каталог системы.
  • TMPDIRявляется канонической переменной среды для изменения местоположения временных файлов. До POSIX, были и другие переменные , используемые, так что я , как правило, идут с первым из этого или TMP, TEMPDIRи TEMPчто имеет значение, понтировавшего и использование системы по умолчанию , если ни один из них не существует.
  • Функции mkstemp()и tempfile()сгенерируют уникальные временные файлы.

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

Blrfl
источник
P_tmpdirне является частью, stdio.hкак определено в спецификации языка C. Это может быть определено POSIX или SVID.
Musiphil
1
@musiphil: Как следует из (теперь уточненного) ответа, это часть POSIX. (Технически это расширение X / Open System, которое включено в POSIX. См. Pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl,
Полностью согласен со всем вышесказанным. Хорошим примером являются системы Linux с pam_tmpdir- это устанавливает TMPDIRи TMPбудет отличаться для каждого пользователя, для надежности и конфиденциальности. Также полезно иметь возможность устанавливать TMPDIRдля одной команды - если у вас есть обычный временный каталог в файловой системе RAM для скорости, вам может потребоваться сделать это для команд, которые генерируют огромные временные файлы (например, гигантские sort). Не игнорируйте стандарты / соглашения, которые ожидают ваши пользователи!
Тоби Спейт
Обязательно проверяйте окружение на наличие временных файлов и никогда не используйте жесткий код / ​​tmp. Поскольку у общего tmp есть проблемы с безопасностью, я часто встречал одно смягчение - создание каталогов для каждого пользователя / tmp без разрешения на чтение и запись для кого-либо еще. Это устраняет возможные условия гонки и атаки по символическим ссылкам.
Zan Lynx
9

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

Под ms-windows у каждого пользователя есть свой временный каталог.

Вы должны использовать createTempFile () для этого, если такая функция доступна.

k3b
источник
1
Просто помните о скрытых ограничениях ОС в Windows. Мы обнаружили, что максимальное количество файлов в папке ограничено 65 565. Конечно, это очень много файлов, и конечно, вы никогда не должны предположительно иметь , что многие прокладки вокруг. Но уверены ли вы , что каждое приложение своевременно и хорошо ведет себя в чистоте?
Майк Хофер
Ах, я видел ваш комментарий слишком поздно. Я просто написал то же самое выше. Кстати, ограничение в основном связано с механикой функции GetTimeFileName (), а не NTFS. Упомянутый вами предел папок применяется только к FAT32 .
JensG
9

Предыдущие ответы, хотя и правильные, не подходят для большинства крупномасштабных компьютерных кластеров.

Компьютерные кластеры не всегда следуют стандартным соглашениям для машин, обычно по уважительным причинам, и нет смысла обсуждать это с системными администраторами.

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

Вычислительные узлы имеют свой собственный жесткий диск, это самая быстрая из доступных файловых систем и то, что вам следует использовать. В документации кластера должно быть указано, что это, как правило /scratch, /tmp/[jobid]или какая-то нестандартная переменная окружения ( $SNIC_TMPв одной из тех, которые я использую).

Итак, я рекомендую сделать его настраиваемым пользователем. Значения по умолчанию могут быть первыми, к которым у вас есть доступ для записи:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

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

Изменить: я добавлю еще одну причину, чтобы заставить его быть установленным пользователем. Один из моих кластеров $TMPDIRнастроен для /scratchзаписи пользователем и находится на локальном жестком диске. Но в документации сказано, что все, что вы пишете вне, /scratch/[jobid]может быть удалено в любой момент, даже в середине цикла. Так что, если вы будете следовать стандартам и доверять $TMPDIR, вы столкнетесь со случайными сбоями, которые очень сложно отладить. Таким образом, вы можете принять $TMPDIR, но не доверять этому.

В некоторых других кластерах эта переменная настроена правильно, поэтому вы можете добавить опцию для явного доверия $TMPDIR, в противном случае выдает большое, жирное предупреждение.

Davidmh
источник
1
Какие именно предыдущие ответы?
Тулаинс Кордова
2
Итак, что вы здесь говорите, так это то, что, поскольку некоторые кластеры, которые не выполняют тривиальный шаг, придерживаясь общепринятого стандарта, сообщающего программам, куда записывать свои временные файлы, это одна дополнительная настройка, специфичная для кластера, для каждой программы. Довольно слабый чай, если вы спросите меня.
Blrfl
@Blrfl, вы можете размахивать стандартами столько, сколько хотите, и писать код, который идеально им соответствует и всегда дает сбой; вы можете попытаться бороться с системными администраторами каждого кластера, который вы используете; или вы можете принять вашу веру и сделать ее настраиваемой. Кроме того, в HPC обычно все равно необходимо адаптировать код к специфике кластера (доступная оперативная память, относительная скорость файловых систем, реализация MPI, общая доступность ресурсов ...), нет «одного размера для всех».
Davidmh
@Davidmh: Понятно, но не в этом суть. Стандарт делает его настраиваемым не удивительным образом. Если я перенесу код, соответствующий известным стандартам, в кластер, где не соблюдаются стандарты, я должен установить его в одном месте, например, в точке входа. В остальной части кода это на одну вещь меньше для аудита, модификации и риска ошибиться.
Blrfl
1

Для многих приложений вам следует рассмотреть возможность размещения временных файлов в $XDG_RUNTIME_DIRили $XDG_CACHE_HOME(другие каталоги XDG предназначены для не временных файлов). Инструкции по их вычислению, если они явно не передаются в среде, см. В спецификации XDG basedir или в библиотеке, которая уже реализует эту часть.

Тем не менее, обратите внимание, что $XDG_RUNTIME_DIRэто новое дополнение, и для старых систем не существует стандартного запасного варианта из-за проблем безопасности.

Если ни один из них не подходит, то /tmpэто правильное место. Вы никогда не должны предполагать, что текущий каталог доступен для записи.

o11c
источник
-2

Это больше похоже на альтернативу, но вы можете сразу отменить ссылку () на файл после fopen (). Это зависит от модели использования курса.

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

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

Файлы должны быть созданы в / tmp. Если у пользователя нет прав на создание файла, это означает, что система неправильно настроена.

Файлы не могут быть созданы в домашнем каталоге пользователей. Многие пользователи, такие как «nobody», «www-data» и многие другие, не имеют прав на запись в свои домашние каталоги, или они даже chroot () - ed. Обратите внимание, что даже в среде chroot / tmp все еще существует.

Ник
источник
Хотя в целом это может быть хорошей идеей, это не поможет пользователям, у которых нет прав на запись в каталог, в котором должен быть создан файл.
5gon12eder
4
Это также не отвечает на вопрос, куда поместить временные файлы.
Blrfl
Я считаю, что мой ответ как-то важен. Я действительно отредактировал, наверное, более понятным образом.
Ник