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ć).