Oto, co ostatecznie wykorzystałem do niezawodnego utworzenia katalogu tymczasowego, który działa zarówno w systemie Linux, jak i Darwin (wszystkie wersje wcześniejsze niż Mac OS X 10.11), bez kodowania $TMPDIR
lub /tmp
:
mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
Tło:
Komenda GNU mktemp nie wymaga żadnych argumentów. Zwykły mktemp
będzie działać i utworzy plik tymczasowy w katalogu tymczasowym systemu.
Plain mktemp -d
utworzy katalog zamiast pliku, którego chciałbyś użyć w systemie Linux.
(gnu-coreutils)$ man mktemp
> ..
> If DIR is not specified, uses $TMPDIR if set, else /tmp.
> ..
Domyślnie GNU mktemp używa szablonu tmp.XXXXXXXXXX
dla nazwy podkatalogu (lub pliku). Aby dostosować ten szablon, -t
można użyć tej opcji.
Mktemp OSX nie ma domyślnego szablonu i wymaga określenia szablonu. Niestety, gdy GNU mktemp bierze szablon jako -t
opcję, w OSX jest to przekazywane jako argument pozycyjny. Zamiast tego mktemp OSX ma -t
opcję, która oznacza coś innego. -t
Opcja na OSX jest udokumentowane jako „prefix” dla szablonu. Jest rozwinięty do {prefix}.XXXXXXXX
, więc dodaje do niego Xs automatycznie (np. mktemp -d -t example
Może utworzyć example.zEJZWCTQ
w katalogu temp).
Byłem zaskoczony, że w wielu środowiskach Linux, $TMPDIR
jest nie ustawiona domyślnie. Wiele programów CLI obsługuje to ustawienie, ale nadal wymaga ustawień domyślnych /tmp
. Oznacza to, że przekazywanie $TMPDIR/example.XXXXXXXX
do mktemp lub mkdir jest niebezpieczne, ponieważ może tworzyć /example.XXXXXXXX
w katalogu głównym dysku lokalnego (ponieważ $ TMPDIR jest rozbrojony i staje się pustym ciągiem).
W OSX $TMPDIR
zawsze jest ustawiony i (przynajmniej w domyślnej powłoce) nie jest ustawiony na /tmp
(co jest dowiązaniem symbolicznym /private/tmp
), ale na /var/folders/dx/*****_*************/T
. Cokolwiek więc robimy dla OSX, powinno szanować to domyślne zachowanie.
Podsumowując, oto co skończyło się używając do niezawodnie utworzyć katalog tymczasowy, który działa zarówno na Linux i Darwin (Mac OS X), bez sztywno albo $TMPDIR
albo /tmp
:
mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
Pierwsza część dotyczy Linuksa. To polecenie zakończy się niepowodzeniem w systemie Darwin (Mac OS X) z kodem błędu 1
odpowiadającym słowem „wykorzystanie: ...”. Dlatego ignorujemy stderr i zamiast tego uruchamiamy wariant Mac. mytmpdir
Prefiks jest używany tylko na Mac (gdzie wymagana jest opcja, że należy ustawić).
mktemp -d
na OS X 10.11.5 El Capitan i działało to zgodnie z oczekiwaniamifile $(mktemp -d)
::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
mktemp -d -t 'mytmpdir'
w systemie Linux (testowanemktemp
zcoreutils 8.26
), to działa zgodnie z oczekiwaniami.Musisz dostarczyć szablon.
mktemp -d /tmp/foo.XXXX
powinno działać. Nigdy nie widziałam--directory
.--
Sugeruje, że jest to rozszerzenie GNU.źródło
$TMPDIR
gdy jest dostępny, zróbmktemp -d "${TMPDIR:-/tmp}"/foo.XXXX
. Działa to w wersji bash na Macu i dash na Debianie, więc wydaje się przenośne.Zmień
--directory
na-d
. Pierwszy z nich to GNU-ism, ale GNUmktemp
z coreutils również obsługuje-d
. Wmktemp
OS X jest taki sam jak w BSD, więc-d
powinien być dość przenośny wśród systemów, które faktycznie wysyłająmktemp
program.źródło
mktemp -d
i to też nie działa.mktemp
operacyjny OS X wymaga szablonu. Skrypt, którego używasz, zakłada konwencje GNU, które używają domyślnego szablonu, jeśli żaden nie jest dostarczony.XXXXX
że zostanie dostarczony w szablonie, ponieważ ponieważ OS X nie ma pewności, czy istnieje zgodna flaga szablonu?mktemp
na OS X 10.11.5 El Capitan działa dla mniefile $(mktemp -d)
::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
mktemp
dla BSD (w tym OSX ) wymaga szablonu, ale pozwala na dowolną liczbęX
s w szablonie.mktemp
dla systemu Linux nie wymaga szablonu, jednak jeśli szablon jest określony, liczbaX
s musi wynosić 6.Zauważ, że
-t
jest nieaktualny dla GNUmktemp
, więc byłby to kod bardziej przyszłościowyźródło