Ниже приведено то, что я использовал для надежного создания временного каталога, который работает как в Linux, так и в Darwin (все версии до Mac OS X 10.11), без жесткого кодирования $TMPDIR
или /tmp
:
mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
Фон:
Команда GNU mktemp не требует аргументов. Обычный mktemp
будет работать и создает временный файл во временном каталоге системы.
Обычный 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 это передается как позиционный аргумент. Вместо этого в OSX mktemp есть -t
опция, которая означает что-то еще. -t
Вариант на OSX документирован как «префикс» для шаблона. Он расширен до {prefix}.XXXXXXXX
, поэтому он добавляет к нему X автоматически (например, 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. Эта команда не удастся выполнить в Darwin (Mac OS X) с кодом ошибки, 1
ответившим «use: ...». Вот почему мы игнорируем stderr и вместо этого запускаем вариант Mac. mytmpdir
Префикс используется только на Mac (где требуется , чтобы установить , что опция).
mktemp -d
на OS X 10.11.5 El Capitan, и все заработало, как и ожидалосьfile $(mktemp -d)
::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
mktemp -d -t 'mytmpdir'
в Linux (протестировано сmktemp
fromcoreutils 8.26
), оно работает как положено.Вы должны предоставить шаблон.
mktemp -d /tmp/foo.XXXX
должно сработать. Я никогда не видел--directory
. Предполагается,--
что это расширение GNU.источник
$TMPDIR
когда доступно, делайтеmktemp -d "${TMPDIR:-/tmp}"/foo.XXXX
. Это работает в bash на Mac и dash на Debian, поэтому кажется переносимым.Изменить
--directory
на-d
. Первый - это GNU-изм, но GNUmktemp
от coreutils также поддерживает-d
.mktemp
В OS X такое же , как от BSD, так что-d
должно быть довольно переносимым между системами , которые фактически поставляются вmktemp
программу.источник
mktemp -d
, и это тоже не работает.mktemp
OS X требуется шаблон. Используемый скрипт предполагает использование соглашений GNU, в котором используется шаблон по умолчанию, если он не указан.XXXXX
что он будет предоставлен в шаблоне, где, поскольку OS X не уверен, есть ли совместимый флаг шаблона?mktemp
на OS X 10.11.5 El Capitan работает для меняfile $(mktemp -d)
::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
mktemp
для BSD (включая OSX ) требуется шаблон, но он допускает любое количествоX
s в шаблоне.mktemp
для Linux не требует шаблона, однако, если шаблон указан, то числоX
s должно быть 6.Обратите внимание, что
-t
это не рекомендуется для GNUmktemp
, поэтому более перспективный код будетисточник