Виправлення або альтернатива mktemp в OS X


72

Я переглядаю сценарій bash, який написав хтось інший, який використовує mktemp:

TEMP=`mktemp --directory`

Однак ця лінія не працює на моїй машині (OS X 10.6).

Як я можу виправити цю лінію, щоб вона була сумісною * x-like-platform? EDIT: Альтернативної команди також буде достатньо.

Відповіді:


108

Далі - це те, що я в кінцевому підсумку використав для надійного створення тимчасового каталогу, який працює як в Linux, так і в Дарвіні (всі версії до Mac OS X 10.11), без жорсткого кодування $TMPDIRабо /tmp:

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

Фон:

Команда GNU mktemp не потребує аргументів. Plain mktempбуде працювати і створює тимчасовий файл у тимчасовому каталозі системи.

Plain mktemp -dстворить каталог, а не файл, який ви хочете використовувати в Linux.

(gnu-coreutils)$ man mktemp
> ..
> If DIR is not specified, uses $TMPDIR if set, else /tmp.
> ..

За замовчуванням GNU mktemp використовує шаблон tmp.XXXXXXXXXXдля імені підкаталогу (або файла). Для налаштування цього шаблону -tможе бути використана опція.

У mktemp для OSX немає шаблону за замовчуванням і потрібно вказати шаблон. На жаль, де GNU Mktemp бере шаблон як -tваріант, на OSX це передається в якості позиційного аргументу. Натомість у mktemp OSX є -tпараметр, який означає щось інше. -tВаріант на OSX документований як «префікс» для шаблону. Він розширюється до {prefix}.XXXXXXXX, тому він додає Xs автоматично (наприклад, mktemp -d -t exampleможе створити example.zEJZWCTQв темп-каталозі).

Я з подивом виявив , що в багатьох середовищах Linux, $TMPDIRце НЕ встановлюється за умовчанням. Багато програм CLI підтримують його, коли вони встановлені, але все ще потрібні за замовчуванням /tmp. Це означає, що перехід $TMPDIR/example.XXXXXXXXдо mktemp або mkdir небезпечний, оскільки може створюватись /example.XXXXXXXXу кореневому каталозі локального диска (через те, що $ TMPDIR не встановлений та стає порожньою рядком).

У OSX $TMPDIRзавжди встановлюється, і (принаймні, в оболонці за замовчуванням) не встановлюється /tmp(що є символьним посиланням /private/tmp), а /var/folders/dx/*****_*************/T. Тому все, що ми робимо для OSX, повинно шанувати таку поведінку за замовчуванням.

На закінчення, таке , що я в кінцевому підсумку використовувала , щоб надійно створити тимчасовий каталог , який працює як на Linux і Darwin (Mac OS X), без жорсткого кодування або $TMPDIRабо /tmp:

mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`

Перша частина призначена для Linux. Ця команда не вдасться в Дарвіні (Mac OS X) з кодом статусу помилки у 1відповідь на "використання: ...". Ось чому ми ігноруємо stderr і замість цього виконуємо варіант Mac. mytmpdirПрефікс використовується тільки на Mac (де потрібно , щоб встановити , що опція).


12
Дійсно здорово. Інколи інша поведінка OS X дратує.
therealmarv

6
@therealmarv Я б краще сказати, завжди.
Микита Волков

10
Я щойно працював mktemp -dна OS X 10.11.5 El Capitan, і він працював так, як очікувалося file $(mktemp -d):: /var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
Heath Borders

2
Так. Я був здивований, як і ти, що це Just Worked ™.
Хіт Межі

1
Крім того, якщо ви працюєте mktemp -d -t 'mytmpdir'на Linux (перевірено mktempз coreutils 8.26), він працює , як очікувалося.

15

Вам потрібно надати шаблон. mktemp -d /tmp/foo.XXXXповинен працювати. Я ніколи не бачив --directory. Це --дозволяє припустити, що це розширення GNU.


6
Якщо ви хочете використовувати, $TMPDIRколи вони є, зробіть це mktemp -d "${TMPDIR:-/tmp}"/foo.XXXX. Це працює в bash на Mac і тире на Debian, тому здається портативним.
Том Андерсон

9

Змінити --directoryна -d. Перший - це GNU-ism, але GNU mktempвід coreutils також підтримує -d. В mktempOS X те саме, що і в BSD, тому -dмає бути досить портативним серед систем, які фактично постачають mktempпрограму.


Я просто спробував mktemp -d, і це не працює.
міндер.

1
Кайл має повну відповідь. Для mktempOS X потрібен шаблон. Сценарій, який ви використовуєте, передбачає конвенції GNU, в яких використовується шаблон за замовчуванням, якщо жоден не надається.
Джеймс Снерінгер

Проблема полягає в тому, що unix розраховує XXXXXбути включеним у шаблон, де як OS X не впевнений, чи є прапор сумісного шаблону?
користувач3467349

2
mktempна OS X 10.11.5 El Capitan працює на мене file $(mktemp -d)::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
Heath Borders

4
temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX")"
  • mktempдля BSD (включаючи OSX ) потрібен шаблон, але він дозволяє будь-яку кількість Xs у шаблоні.
  • (GNU) mktempдля Linux не вимагає шаблон, однак, якщо шаблон вказаний, то кількість Xs має бути 6.

Зауважте, що -tце застаріле для GNUmktemp , тому більш надійним у майбутньому буде код

temp_dir="$(mktemp -q -d -t "$(basename "$0").XXXXXX" 2>/dev/null || mktemp -q -d)"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.