Чи слід зберігати тимчасові файли в / tmp або поточному робочому каталозі?


76

У мене є програма, якій потрібно генерувати тимчасові файли. Він написаний для кластерних машин.

Якщо я зберегла ці файли у загальносистемному тимчасовому каталозі (наприклад:) /tmp, деякі користувачі скаржилися, що програма не працює, оскільки вони не мали належного доступу до / tmp. Але якщо я зберегла ці файли у робочому каталозі, ці користувачі також поскаржилися, що не хочуть бачити ці загадкові файли.

Яка з них є кращою практикою? Чи потрібно наполягати на тому, що заощадження /tmp- це правильний підхід і захищати будь-який збій як "працює за призначенням" (тобто запитати у адміністратора належного дозволу / доступу)?


3
перевірити, чи має програма доступ, а якщо не знайти іншого темп-dir
ratchet freak

24
Якщо ваш адміністратор накрутив права доступу, він обов'язково повинен виправити це. Що б ви зробили, якщо ваш адміністратор забув додати права виконання на вашу програму?
Док Браун

7
Ви не знайдете / tmp у більшості систем Windows, але є виклик ОС, який підкаже вам, куди слід помістити тимчасові файли.
Ян

28
Якщо деякі люди не мали доступу до /tmpUnix-подібної системи, це неправильно налаштовано. Суперусер повинен щось робити chmod 1777 /tmp.
musiphil

12
Остерігайтеся, що $ TMPDIR може вказувати на інший шлях, ніж той /tmp/, який ви повинні використовувати замість цього. Дивіться деякі відповіді;)
marcelm

Відповіді:


141

Тимчасові файли повинні зберігатися у тимчасовому каталозі операційної системи з кількох причин:

  • Операційна система дозволяє дуже легко створювати ці файли, гарантуючи, що їх імена будуть унікальними .

  • Більшість програм резервного копіювання знає, що це каталоги, що містять тимчасові файли, і пропускає їх. Якщо ви використовуєте поточний каталог, це може мати важливий вплив на розмір покрокових резервних копій, якщо резервні копії робляться часто.

  • Тимчасовий каталог може знаходитися на іншому диску або в оперативній пам'яті, що робить доступ для читання-запису набагато швидше .

  • Тимчасові файли часто видаляються під час перезавантаження (якщо вони знаходяться в ramdisk, вони просто втрачаються). Це зменшує ризик нескінченного зростання, якщо ваш додаток не завжди видаляє тимчасові файли правильно (наприклад, після збоїв).

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

  • Довжина шляху може бути занадто довгою на деяких платформах. Наприклад, для 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"
  • Пітон:

    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);
  • Ruby:

    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()будуть генерувати унікальні тимчасові файли.

Якщо вашим користувачам заборонено створювати тимчасові файли, система або неправильно налаштована, або адміністратори не дають зрозуміти, яка їх політика щодо таких речей. У цих випадках ви будете дуже твердими, сказавши, що ваша програма відповідає усталеному стандарту портативності і що її поведінку можна змінити, використовуючи змінні середовища, які стандарт визначає.


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одну команду - якщо у вас є звичайний тимчасовий каталог у файловій системі оперативної пам’яті для швидкості, можливо, це знадобиться зробити для команд, що генерують величезні тимчасові файли (наприклад, гігантський sort). Не ігноруйте стандартів / умов, яких очікують ваші користувачі!
Toby Speight

Однозначно перевіряйте середовище на наявність тимчасових файлів і ніколи не жорсткого коду / tmp. Оскільки спільний tmp має проблеми із безпекою, я часто бачив таке пом'якшення - це створювати каталоги на кожного користувача / tmp без дозволу читання та запису для когось іншого. Це усуває можливі умови перегонів і атаки символьних ліній.
Зан Лінкс

9

Temp-файл-каталог залежить від операційної системи / середовища. Наприклад, веб-сервери-temp dir відокремлюються від os-temp-dir з міркувань безпеки.

Під ms-windows кожен користувач має власний темп-реж.

для цього слід використовувати createTempFile (), якщо така функція доступна.


1
Пам’ятайте лише про приховані обмеження ОС у Windows. Ми виявили важкий шлях, що максимальна кількість файлів у папці була обмежена 65 655. Звичайно, це дуже багато файлів, і звичайно, ви ніколи не повинні імовірно мати , що багато прокладки навколо. Але ви впевнені, що кожен додаток очищається після себе своєчасно та добре поводиться?
Майк Хофер

Ах, я бачив ваш коментар занадто пізно. Я саме написав те саме вище. BTW межа обмежується насамперед механікою функції GetTimeFileName (), а не NTFS. Цей згаданий вами ліміт папок стосується лише FAT32 .
JensG

9

Попередні відповіді, хоча і правильні, не вірні для більшості масштабних комп'ютерних кластерів.

Комп'ютерні кластери не завжди дотримуються стандартних умов для машин, як правило, з поважних причин, і немає сенсу обговорювати це з систематинами.

Ваш поточний каталог посилається на центральну файлову систему, до якої можна отримати доступ через мережу. Це не тільки повільно, але також навантажує систему для решти користувачів, тому не слід користуватися нею, якщо ви не пишете багато і не зможете відновитись, якщо робота завершиться.

У обчислювальних вузлах є власний жорсткий диск, тобто найшвидша наявна файлова система та те, що ви повинні використовувати. Документація кластера повинна говорити про те, що це, як правило /scratch, /tmp/[jobid]або якась нестандартна змінна середовище ( $SNIC_TMPв одній із тих, які я використовую).

Отже, те, що я рекомендую, - це зробити його налаштованим користувачем. Значення за замовчуванням можуть бути першими, до яких ви маєте доступ до запису:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Але очікуйте, що при такому підході низький показник успіху, і переконайтеся, що ви маєте велике попередження про жир.

Редагувати: я додам ще одну причину змусити його встановити користувача. Один з моїх кластерів $TMPDIRвстановив /scratch, що це доступний для запису користувачем та на локальному жорсткому диску. Але в документації сказано, що все, що ви пишете поза, /scratch/[jobid]може бути видалено в будь-якій точці, навіть у середині пробігу. Отже, якщо ви будете дотримуватися стандартів і довіряти $TMPDIR, ви зіткнетеся з випадковими збоями, дуже важкими для налагодження. Отже, ви можете прийняти $TMPDIR, але не довіряти цьому.

У деяких інших кластерах ця змінна правильно налаштована, тому ви можете додати опцію, щоб явно довіряти $TMPDIR, інакше надсилати велике, жирне попередження.


1
Які саме є попередні відповіді?
Тулен Кордова

2
Отож, що ви тут говорите, це те, що деякі кластери, які не роблять тривіального кроку дотримання чітко встановленого стандарту повідомляти програмам, де писати їх тимчасові файли, це одна додаткова настройка для кластера, необхідна для кожної програми. Досить слабкий чай, якщо ви запитаєте мене.
Blrfl

@Blrfl ви можете махати стандартами скільки завгодно, і писати код, який ідеально дотримується їх і завжди виходить з ладу; ви можете спробувати поборотись із систематичними системами кожного кластеру, який ви використовуєте; або ви можете прийняти свою віру і зробити її настроюваною. Крім того, в HPC зазвичай так чи інакше потрібно адаптувати код до специфіки кластера (доступна оперативна пам'ять, відносна швидкість файлових систем, реалізація MPI, загальна доступність ресурсів ...), немає "одного розміру, який підходить усім".
Давідм

@Davidmh: Зрозумів, але не в цьому суть. Стандарт робить його налаштованим не дивно. Якщо я переношу відомий відповідний код до кластеру, де стандарт не дотримується, я повинен встановити його саме в одному місці, наприклад, у точці входу. Це одна річ у решті коду - перевірити, змінити та ризикувати помилитися.
Blrfl

1

У багатьох програмах слід розглянути можливість розміщення тимчасових файлів у ( $XDG_RUNTIME_DIRабо $XDG_CACHE_HOMEінші dir-файли XDG призначені для тимчасових файлів). Інструкції щодо їх обчислення, якщо вони явно не передані в навколишнє середовище, див. Специфікацію на основі XDG або знайдіть бібліотеку, яка вже реалізує цю частину.

Однак зауважте, що $XDG_RUNTIME_DIRце нове доповнення, і немає стандартних резервних можливостей для старих систем через проблеми безпеки.

Якщо жодне з них не підходить, то /tmpце правильне місце. Ніколи не слід вважати, що поточний каталог можна записати.


-2

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

Від’єднання файлів, якщо це можна зробити, допомагає декількома способами:

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

Файли повинні бути створені в / tmp. Якщо користувач не має прав на створення файлу там, це означає, що система не налаштована.

Файли неможливо створити в домашньому каталозі користувачів. Багато користувачів, такі як "ніхто", "www-data" та багато інших, не мають права писати у своїх домашніх довідниках, або вони навіть chroot () - ред. Зауважте, що навіть у середовищі chroot / tmp все ще існує.


Хоча це може бути хорошою ідеєю в цілому, це не допомагає користувачам, яким бракує дозволів на запис у каталог, у якому повинен бути створений файл.
5gon12eder

4
Він також не відповідає на питання, куди слід розміщувати тимчасові файли.
Blrfl

Я вважаю, що моя відповідь якось важлива. Я зробив редагування, мабуть, це більш зрозуміло.
Нік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.