GNU/Linux >> Belajar Linux >  >> Linux

Mktemp Di Macos Tidak Menghormati $tmpdir?

Saya telah memperhatikan ini sebelumnya, tetapi muncul lagi ketika saya menjawab “Bagaimana cara memindahkan direktori ke direktori dengan nama yang sama?“:

mktemp utilitas di macOS tidak berperilaku sama dengan utilitas dengan nama yang sama di Linux atau BSD (atau paling tidak OpenBSD) sehubungan dengan TMPDIR variabel lingkungan.

Untuk membuat file sementara di saat ini direktori, saya biasanya bisa mengatakan

tmdfile=$(TMPDIR=. mktemp)

atau

tmpfile=$(TMPDIR=$PWD mktemp)

(dan juga untuk direktori sementara dengan mktemp -d ).

Di macOS, saya harus memaksa utilitas untuk menggunakan direktori saat ini dengan memberikannya templat yang sebenarnya, seperti pada

tmpfile=(mktemp ./tmp.XXXXXXXX)

karena lebih nyaman menggunakan tmpfile=$(TMPDIR=. mktemp) akan mengabaikan TMPDIR variabel dan buat file di bawah /var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T atau di direktori bernama serupa.

Manual untuk mktemp di macOS menyebutkan bahwa

Jika -t prefix pilihan diberikan, mktemp akan menghasilkan string template berdasarkan awalan dan
_CS_DARWIN_USER_TEMP_DIR variabel konfigurasi jika tersedia. Lokasi penggantian jika
_CS_DARWIN_USER_TEMP_DIR tidak tersedia adalah TMPDIR dan /tmp .

Di sistem saya, _CS_DARWIN_USER_TEMP_DIR tampaknya tidak disetel:

$ getconf _CS_DARWIN_USER_TEMP_DIR
getconf: no such configuration parameter `_CS_DARWIN_USER_TEMP_DIR'

tetapi misalnya

tmpfile=$(TMPDIR=. mktemp -t hello)

masih membuat file di bawah /var/folders/.../ (juga saat menggunakan $PWD sebagai pengganti . ).

Saya perhatikan itu

$ getconf DARWIN_USER_TEMP_DIR
/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/T/

tetapi ini tidak banyak membantu saya karena saya tidak tahu bagaimana mengubah nilai ini.

mktemp macOS utilitas dikatakan berasal dari FreeBSD, yang pada gilirannya mendapatkannya dari OpenBSD (yang pasti sudah cukup lama).

Pertanyaan:

Apakah ini bug (atau kelalaian) dalam implementasi macOS mktemp ? Bagaimana cara mengubah DARWIN_USER_TEMP_DIR nilai (atau _CS_DARWIN_USER_TEMP_DIR disebutkan oleh manual) dari dalam skrip (idealnya saya ingin menghapusnya sehingga $TMPDIR diutamakan)?

Jawaban yang Diterima:

/var/folders/qg/s5jp5ffx2p1fxv0hy2l_p3hm0000gn/

Ini adalah pengguna lokal Darwin Anda direktori. Namanya hanyalah pengkodean basis 32 yang dimodifikasi dari rangkaian MacOS Anda UUID Pengguna dan ID pengguna MacOS (BSD) Anda. Dua huruf pertama dari pengkodean digunakan sebagai sistem "ember" untuk mencoba menjaga ukuran direktori tetap rendah. Kedua karakter tersebut adalah 10 bit pertama yang dikodekan dari UUID Pengguna, karena di basis 32 satu digit tentu saja 5 bit.

Subdirektorinya adalah suhu lokal pengguna Anda dan cache lokal pengguna direktori. Nama mereka dulunya -Caches- dan -Tmp- tapi itu telah disingkat menjadi C dan T . Seharusnya jelas bahwa semua nama ini tetap dan tidak dapat diubah, kecuali jika Anda ingin mengubah ID pengguna atau UUID pengguna Anda.

Saat aplikasi memanggil confstr(_CS_DARWIN_USER_TEMP_DIR,…) , pustaka C pertama-tama mencoba memastikan bahwa Anda memiliki pengguna lokal direktori, kemudian mencoba memastikan bahwa Anda memiliki suhu lokal pengguna direktori di dalamnya.

Terkait:Linux – Bagaimana cara meneruskan lalu lintas antara ruang nama jaringan Linux?

Memastikan bahwa Anda memiliki pengguna lokal direktori non-sepele, karena Anda tidak memiliki akses tulis ke /var/folders . Jadi ada dirhelper Mach launch dmon yang berjalan dengan hak pengguna super dan yang membuat direktori ini dengan aman, menanggapi panggilan IPC Mach dari aplikasi dari dalam implementasi confstr() di perpustakaan C mereka. Anda melakukannya memiliki akses tulis ke pengguna lokal direktori (setelah dibuat) dan pustaka C hanya mkdir() anak-anaknya secara langsung jika mereka belum ada.

Jika berhasil, mktemp program tidak pernah melihat nilai TMPDIR variabel lingkungan, karena fallback di mktemp kode ini dari memanggil confstr() untuk memanggil getenv() bukan sebaliknya. confstr(_CS_DARWIN_USER_TEMP_DIR,…) hampir selalu berhasil. Mode kegagalannya adalah hal-hal seperti dirhelper peluncuran setan tidak dapat dijalankan, atau upaya untuk membuat T subdirektori gagal dengan kesalahan selain bahwa direktori sudah ada.

Anda dapat meletakkan sesuatu selain direktori sebagai T , tetapi ini akan dibersihkan secara teratur oleh dirhelper luncurkan dmon, yang juga menghapus hal-hal di /var/folders . Menonaktifkan dirhelper peluncuran dæmon akan menyebabkan masalah sendiri, tidak sedikit yang akan menjadi /var/folders tidak dibersihkan. Menolak izin menulis Anda sendiri di pengguna lokal direktori akan berpotensi mengganggu semua lainnya penggunaannya, itu digunakan untuk lebih dari sekadar T subdirektori.

Pilihan terbaik Anda (selain menyediakan template) adalah membuat T tautan simbolik, tetapi ini masih jauh dari baik karena tentu saja akan memengaruhi semua aplikasi Anda yang sedang berjalan yang mungkin, pada saat yang sama, ingin membuat file sementara.

Baik DARWIN_USER_TEMP_DIR atau _CS_DARWIN_USER_TEMP_DIR adalah nama variabel. Itu adalah nama, untuk getconf utilitas dan untuk confstr() fungsi library, dari string konfigurasi.


Linux
  1. Hapus Semua File Dalam Direktori Yang Namanya Tidak Cocok Dengan Baris Dalam Daftar File?

  2. Perintah `ls` Tidak Mencantumkan Konten Direktori Terbaru?

  3. Mengapa Rm -rf Dan Bukan Rmdir -rf?

  1. Cara menjalankan perintah "find" hanya pada direktori saat ini dan bukan pada sub-direktori

  2. SVN memeriksa isi folder, bukan folder itu sendiri

  3. Inti dibuang, tetapi file inti tidak ada di direktori saat ini?

  1. file_put_contents tidak membuat file txt

  2. Mengapa tautan simbolis saya membuat file dan bukan folder?

  3. Transmisi-daemon tidak mengambil direktori jam tangan