Berikut ini adalah apa yang akhirnya saya gunakan untuk secara andal membuat direktori sementara yang berfungsi pada Linux dan Darwin (semua versi sebelum Mac OS X 10.11), tanpa hardcoding $TMPDIR
atau /tmp
:
mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
Latar Belakang:
Perintah mktemp GNU tidak membutuhkan argumen. Plain mktemp
akan bekerja dan membuat file sementara di direktori sementara sistem.
Plain mktemp -d
akan membuat direktori alih-alih file, yang ingin Anda gunakan di Linux.
(gnu-coreutils)$ man mktemp
> ..
> If DIR is not specified, uses $TMPDIR if set, else /tmp.
> ..
Secara default, mktemp GNU menggunakan templat tmp.XXXXXXXXXX
untuk nama sub direktori (atau file). Untuk menyesuaikan template ini, -t
opsi dapat digunakan.
Mktemp OSX tidak memiliki templat default dan mengharuskan templat ditentukan. Sayangnya, ketika GNU mktemp mengambil templat sebagai -t
opsi, pada OSX ini dilewatkan sebagai argumen posisi. Sebaliknya, mktemp OSX memiliki -t
opsi yang berarti sesuatu yang lain. The -t
pilihan pada OSX didokumentasikan sebagai "awalan" untuk template. Ini diperluas ke {prefix}.XXXXXXXX
, jadi itu menambahkan Xs ke secara otomatis (misalnya mktemp -d -t example
dapat membuat example.zEJZWCTQ
di direktori temp).
Saya terkejut menemukan bahwa di banyak lingkungan Linux, $TMPDIR
yang tidak diatur secara default. Banyak program CLI yang mendukungnya ketika diatur, tetapi masih membutuhkan default untuk itu /tmp
. Ini berarti meneruskan $TMPDIR/example.XXXXXXXX
ke mktemp atau mkdir berbahaya karena dapat menghasilkan /example.XXXXXXXX
di direktori root disk lokal (karena $ TMPDIR tidak disetel dan menjadi string kosong).
Pada OSX, $TMPDIR
selalu diatur dan (setidaknya di shell default) tidak diatur ke /tmp
(yang merupakan symlink ke /private/tmp
) tetapi ke /var/folders/dx/*****_*************/T
. Jadi apa pun yang kita lakukan untuk OSX, harus menghormati perilaku default itu.
Sebagai kesimpulan, berikut ini adalah apa yang akhirnya saya gunakan untuk membuat direktori sementara yang berfungsi baik pada Linux dan Darwin (Mac OS X), tanpa hardcoding, salah satu $TMPDIR
atau /tmp
:
mytmpdir=`mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir'`
Bagian pertama adalah untuk Linux. Perintah ini akan gagal pada Darwin (Mac OS X) dengan kode status kesalahan 1
merespons dengan "penggunaan: ...". Itu sebabnya kami mengabaikan stderr dan malah menjalankan varian Mac. The mytmpdir
prefix hanya digunakan pada Mac (di mana opsi yang diperlukan untuk mengatur).
mktemp -d
pada OS X 10.11.5 El Capitan, dan itu bekerja seperti yang diharapkanfile $(mktemp -d)
::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
mktemp -d -t 'mytmpdir'
di Linux (diuji denganmktemp
daricoreutils 8.26
), itu berfungsi seperti yang diharapkan.Anda harus menyediakan templat.
mktemp -d /tmp/foo.XXXX
harus bekerja. Saya belum pernah melihatnya--directory
. Yang--
menunjukkan bahwa itu adalah ekstensi GNU.sumber
$TMPDIR
saat tersedia, lakukanmktemp -d "${TMPDIR:-/tmp}"/foo.XXXX
. Itu bekerja di bash di Mac dan lari di Debian, jadi sepertinya portabel.Ubah
--directory
ke-d
. Yang pertama adalah GNU-isme, tetapi GNUmktemp
dari coreutils juga mendukung-d
. Themktemp
di OS X adalah sama dengan dari BSD, sehingga-d
harus cukup portabel di antara sistem yang benar-benar kapalmktemp
Program.sumber
mktemp -d
, dan tidak berhasil juga.mktemp
OS X memerlukan templat. Skrip yang Anda gunakan mengasumsikan konvensi GNU, yang menggunakan templat default jika tidak ada yang disediakan.XXXXX
untuk disediakan dalam template sedangkan OS X tidak yakin apakah ada flag template yang kompatibel?mktemp
pada OS X 10.11.5 El Capitan bekerja untuk sayafile $(mktemp -d)
::/var/folders/j4/htlnmbf97vlcdszj7_x8g0vh4k3_fp/T/tmp.JXmsrQnL: directory
mktemp
untuk BSD (termasuk OSX ) memerlukan templat, tetapi ini memungkinkan sejumlahX
s dalam templat.mktemp
untuk Linux tidak memerlukan templat, namun, jika templat ditentukan, maka jumlahX
s harus 6.Catatan yang
-t
sudah usang untuk GNUmktemp
, jadi kode yang lebih tahan akan masa depansumber