Пошук правильного tmp dir на кількох платформах


46

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

Сценарій повинен працювати на декількох платформах: Git Bash (Windows), Solaris, Linux, OSX. На кожній платформі бажаний тимчасовий каталог виражається по-різному:

  • Windows: %TMP%(і можливо %TEMP%)
  • OSX: $TMPDIR
  • Linux, UNIX: мабуть, $TMPDIRале, здається, не налаштовано на декілька систем, які я намагався

Тож у своєму сценарії я додав цю котельню:

if test -d "$TMPDIR"; then
    :
elif test -d "$TMP"; then
    TMPDIR=$TMP
elif test -d /var/tmp; then
    TMPDIR=/var/tmp
else
    TMPDIR=/tmp
fi

Це здається занадто нудним. Чи є кращий спосіб?


6
Просто використовуйте ${TMPDIR-/tmp}Unix-лайки. TMPDIRє (система чи адміністратор чи користувач), щоб сказати вам, коли не використовувати /tmpтимчасові файли.
Стефан Шазелас

Відповіді:


72

Трохи більш портативний спосіб обробки тимчасових файлів - це використання mktemp. Він створить тимчасові файли та поверне їх шляхи для вас. Наприклад:

$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P

Ви можете використовувати його в сценарії досить легко:

tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile

Читаючи сторінку чоловіка, ви повинні мати можливість встановлювати параметри відповідно до своїх потреб. Наприклад:

  • -d створює каталог замість файлу.
  • -u генерує ім’я, але нічого не створює.

Використовуючи -uви можете отримати тимчасовий каталог досить легко за допомогою ...

$ tmpdir=$(dirname $(mktemp -u))

Більше інформації mktempможна отримати тут .

Редагування щодо Mac OS X: Я ніколи не використовував систему Mac OSX, але згідно з коментарем Тайло нижче, схоже, що для Mac OSX mktempпотрібно надати вам шаблон (що є необов'язковим аргументом в Linux). Цитування:

Шаблоном може бути будь-яке ім'я файлу, наприклад, до нього додається деяка кількість "X" /tmp/temp.XXXX. Кінцеві "X" замінюються поточним номером процесу та / або унікальною комбінацією літер. Кількість унікальних імен файлів, які може повернути mktemp, залежить від кількості наданих "Xs"; шість "X" призведе до того, що mktemp вибере 1 з 56800235584 (62 ** 6) можливих імен файлів.

На сторінці man також йдеться, що ця реалізація натхненна довідковою сторінкою OpenBSD mktemp. Таким чином, подібні розбіжності можуть спостерігатися і у користувачів OpenBSD та FreeBSD (див. Розділ « Історія» ).

Тепер, як ви, напевно, помітили, для цього потрібно вказати повний шлях до файлу, включаючи тимчасовий каталог, який ви шукаєте у своєму запитанні. З цією малою проблемою можна впоратися за допомогою -tперемикача. Незважаючи на те, що цей варіант, як видається, вимагає аргументу ( prefix), але, здається, mktempпокладається на $TMPDIRнеобхідність.

Загалом, ви повинні мати можливість отримати той же результат, що і вище, використовуючи ...

$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))

Будь-які відгуки користувачів Mac OS X були б вдячні, оскільки я не в змозі перевірити це рішення самостійно.


ОП вирішило це питання у видаленому коментарі; Я боюся, що не можу дати відповідь для систем, які потребують gitbashотримання інтерфейсу оболонки, звідси моє "трохи". Я насправді не зможу сказати, де зберігаються тимчасові файли в системі Windows ...
Джон У. Сміт

1
Ditto що. Якийсь божевільний c:\User\Name\..............\stuff. І їх, мабуть, 100. Тим не менш, деякі дистрибутиви Linux наближаються до того ж рівня божевілля в /var. Мені було просто цікаво. Мене це вразило як дивний спосіб сказати, що це все - на мій досвід, розчарування дуже портативні, а зручність - не так. Дуже гарна відповідь у будь-якому випадку.
mikeserv

1
Ще рік тому я написав сценарій Bash для маніпулювання файлами Windows Restore Point, які працюють на Win2K через WinXP (пізніші версії обробляють це по-різному). Мій сценарій використовує WINDOWS/Tempабо Windows/Tempяк каталог за замовчуванням для своїх тимчасових файлів; цей каталог також існує на машинах Windows 7. Але мій сценарій дозволяє користувачеві подавати альтернативний тимчасовий dir у командному рядку.
14:00 14

Це не буде працювати в OS X, оскільки вам потрібно надати шаблон mktemp.
Тіїло

1
Оскільки El Capitan mktempпросто працює: просто mktempповертає файл і mktemp -dповертає каталог; не потрібні шаблони. Керівництво не оновлюється , хоча.
Франклін Ю

9

Якщо ви шукаєте те саме в меншій кількості рядків ...

for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
    test -d "$TMPDIR" && break
done

Ви можете написати це одним.


Ви, ймовірно, також повинні перевірити, чи це можливо для запису.
frostschutz

@janos: А якщо все інше не вдається, попросіть користувача надати шлях для тимчасових файлів або дозвольте їм вказати один у командному рядку.
14:00 14

6

Ви можете зробити:

: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit

Оболонка повинна або знайти виконавчий каталог в одній із 4 альтернатив, або вийти зі значущою помилкою. Але POSIX визначає $TMPDIRзмінну (для систем XCU) :

TMPDIR Ця змінна повинна представляти ім'я довідника, доступного для програм, яким потрібне місце для створення тимчасових файлів.

Це також вимагає /tmpшлях.


1
Це єдина правильна відповідь тут ІМО. Не знаю, що це робить, сідаючи на дно, не голосуючи ...
Граме

2
@Graeme: можливо тому, що це абсолютно нечитабельно?
ssc

Я схвалив, але потім відкликав його - так, ця відповідь - це безлад. Це, здається, є корисним шляхом, але зовсім не ясно, що намагається зробити фрагмент коду - перший рядок - це коментар, а другий один - це помилка (в базі, все одно). Може використати якусь роботу.
Дон Хетч

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