Haruskah file sementara disimpan ke / tmp atau direktori kerja saat ini?

76

Saya memiliki program yang perlu membuat file sementara. Ini ditulis untuk mesin cluster.

Jika saya menyimpan file-file itu ke direktori sementara seluruh sistem (misalnya:) /tmp, beberapa pengguna mengeluh program gagal karena mereka tidak memiliki akses yang tepat ke / tmp. Tetapi jika saya menyimpan file-file itu ke direktori kerja, para pengguna itu juga mengeluh mereka tidak ingin melihat file-file misterius itu.

Yang mana yang merupakan praktik yang lebih baik? Haruskah saya bersikeras bahwa menabung /tmpadalah pendekatan yang tepat dan membela setiap kegagalan sebagai "berfungsi sebagaimana dimaksud" (mis. Minta admin Anda untuk izin / akses yang tepat)?

Catur kecil
sumber
3
periksa apakah program memiliki akses dan jika tidak menemukan dir temp
ratchet freak lainnya
24
Jika admin Anda mengacaukan hak akses, ia pasti harus memperbaikinya. Apa yang akan Anda lakukan jika admin Anda lupa menambahkan hak eksekusi ke program Anda?
Doc Brown
7
Anda tidak akan menemukan / tmp pada kebanyakan sistem windows, tetapi ada panggilan OS yang akan memberi tahu Anda di mana harus meletakkan file temp.
Ian
28
Jika beberapa orang tidak memiliki akses ke /tmpsistem seperti Unix, itu salah konfigurasi. Superuser harus melakukan sesuatu seperti chmod 1777 /tmp.
musiphil
12
Berhati-hatilah karena $ TMPDIR mungkin mengarah ke jalur yang berbeda dari /tmp/yang seharusnya Anda gunakan. Lihat beberapa jawaban;)
marcelm

Jawaban:

141

File sementara harus disimpan ke direktori sementara sistem operasi karena beberapa alasan:

  • Sistem operasi membuatnya sangat mudah untuk membuat file-file itu sambil memastikan bahwa nama mereka akan unik .

  • Sebagian besar perangkat lunak cadangan tahu apa saja direktori yang berisi file sementara, dan melewatkannya. Jika Anda menggunakan direktori saat ini, ini bisa memiliki efek penting pada ukuran cadangan tambahan jika cadangan sering dilakukan.

  • Direktori sementara mungkin pada disk yang berbeda, atau dalam RAM, membuat akses baca-tulis jauh lebih cepat .

  • File sementara sering dihapus selama reboot (jika mereka berada di ramdisk, mereka hilang begitu saja). Ini mengurangi risiko pertumbuhan tanpa batas jika aplikasi Anda tidak selalu menghapus file temp dengan benar (misalnya setelah crash).

    Membersihkan file temp dari direktori kerja dapat dengan mudah menjadi berantakan jika file disimpan bersama dengan file aplikasi dan pengguna. Anda dapat mengurangi masalah ini dengan membuat direktori terpisah di dalam direktori saat ini, tetapi ini dapat menyebabkan masalah lain:

  • The Panjang jalan bisa terlalu lama pada beberapa platform. Misalnya, di Windows, batas jalur untuk beberapa API, kerangka kerja dan aplikasi mengerikan , yang berarti bahwa Anda dapat dengan mudah mencapai batas tersebut jika direktori saat ini sudah jauh di hierarki hierarki dan nama file sementara Anda terlalu panjang.

  • Di server, memantau pertumbuhan direktori sementara sering dilakukan dengan segera. Jika Anda menggunakan direktori yang berbeda, itu mungkin tidak dipantau, dan memantau seluruh disk tidak akan membantu untuk dengan mudah mengetahui bahwa itu adalah file temp yang mengambil semakin banyak tempat.

Adapun kesalahan akses ditolak, pastikan Anda membiarkan sistem operasi membuat file sementara untuk Anda. Sistem operasi dapat, misalnya, mengetahui bahwa untuk pengguna tertentu, direktori selain /tmpatau C:\Windows\tempharus digunakan; dengan demikian, dengan mengakses direktori tersebut secara langsung, Anda mungkin memang menemukan kesalahan akses ditolak.

Jika Anda mendapatkan akses ditolak bahkan ketika menggunakan panggilan sistem operasi, yah, itu berarti bahwa mesin itu dikonfigurasi dengan buruk; ini sudah dijelaskan oleh Blrfl . Terserah administrator sistem untuk mengkonfigurasi mesin; Anda tidak perlu mengubah aplikasi Anda.

Membuat file sementara sangat mudah dalam banyak bahasa. Beberapa contoh:

  • Pesta:

    # The next line will create a temporary file and return its path.
    path="$(mktemp)"
    echo "Hello, World!" > "$path"
    
  • Python:

    import tempfile
    
    # Creates a file and returns a tuple containing both the handle and the path.
    handle, path = tempfile.mkstemp()
    with open(handle, "w") as f:
        f.write("Hello, World!");
    
  • C #:

    // Creates a file and returns the path.
    var path = Path.GetTempFileName();
    File.WriteAllText(path, "Hello, World!");
    
  • PHP:

    # Creates a file and returns the handle.
    $temp = tmpfile();
    fwrite($temp, "Hello, World!");
    fclose($temp);
    
  • Rubi:

    require "tempfile"
    
    # Creates a file and returns the file object.
    file = Tempfile.new ""
    file << "Hello, World!"
    file.close
    

Perhatikan bahwa dalam beberapa kasus, seperti dalam PHP dan Ruby, file dihapus ketika pegangan ditutup. Itu manfaat tambahan menggunakan perpustakaan yang dibundel dengan bahasa / kerangka kerja.

Arseni Mourzenko
sumber
2
Apa yang Anda maksud dengan "pastikan Anda membiarkan sistem operasi membuat file sementara untuk Anda". Jadi, alih-alih misalnya fopen("/tmp/mytmpfile", "w");saya harus membuat panggilan sistem untuk menangani file sementara?
simon
30
@ gurka: Anda harus menelepon tmpfile(3)untuk membuat file sementara, atau setidaknya menelepon mktemp(3)untuk membuat nama file.
TMN
3
@ TMN: Itu hanya fungsi pustaka yang berjalan di ruang pengguna, dan mereka tidak memiliki sihir untuk memintas kesalahan izin yang diberikan oleh sistem operasi.
musiphil
25
@musiphil Baik tmpfile dan mktemp menggunakan variabel eksternal untuk menentukan path untuk file sementara. Ini mungkin telah diatur untuk menunjuk ke direktori lain selain / tmp /, mungkin direktori per pengguna. Mencoba membuat nama file secara manual di / tmp / mungkin gagal, sementara tmpfile dan mktemp akan mengembalikan jalur yang valid.
pipa
2
@ Musiphil: Saya tidak pernah mengatakan mereka akan memperbaiki masalah izin, saya menanggapi pertanyaannya tentang menggunakan panggilan sistem untuk membuat file.
TMN
33

Haruskah saya bersikeras menyimpan ke / tmp adalah pendekatan yang tepat dan membela setiap kegagalan sebagai "berfungsi sebagaimana dimaksud" (mis. Minta admin Anda untuk akses izin yang tepat)?

Ada standar untuk ini, dan hal terbaik yang dapat Anda lakukan adalah menyesuaikannya.

POSIX, yang diikuti oleh hampir semua OS non-mainframe dengan signifikansi apa pun yang kemungkinan besar akan Anda hadapi, memiliki ketentuan untuk membuat file sementara yang dinamai unik dalam direktori menggunakan nilai default yang dapat dikonfigurasi ulang oleh lingkungan:

  • stdio.hHeader C secara opsional dapat menyertakan P_tmpdirmakro yang menamai direktori sementara sistem.
  • TMPDIRadalah variabel lingkungan kanonik untuk mengubah lokasi file sementara. Sebelum POSIX, ada variabel lain yang digunakan, jadi saya cenderung pergi dengan yang pertama atau TMP, TEMPDIRdan TEMPyang memiliki nilai, punting dan menggunakan sistem default jika tidak ada yang ada.
  • Fungsi mkstemp()dan tempfile()akan menghasilkan file sementara yang unik.

Jika pengguna Anda ditolak kemampuan untuk membuat file sementara, sistem salah konfigurasi atau administrator tidak menjelaskan apa kebijakan mereka tentang hal-hal seperti itu. Dalam kasus tersebut, Anda akan sangat kuat dalam mengatakan bahwa program Anda sesuai dengan standar portabilitas yang sudah mapan dan bahwa perilakunya dapat diubah menggunakan variabel lingkungan yang ditentukan oleh standar.

Blrfl
sumber
P_tmpdirbukan bagian dari yang stdio.hdidefinisikan oleh spesifikasi bahasa C. Mungkin didefinisikan oleh POSIX atau SVID.
musiphil
1
@musiphil: Seperti yang tersirat oleh jawaban (sekarang-diklarifikasi), itu bagian dari POSIX. (Secara teknis, ini adalah X / Sistem Terbuka Ekstensi yang dimasukkan POSIX. Lihat pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl
Sepenuhnya setuju dengan semua hal di atas. Contoh yang baik adalah sistem Linux dengan pam_tmpdir- set ini TMPDIRdan TMPmenjadi berbeda untuk setiap pengguna, untuk ketahanan dan privasi. Ini juga berguna untuk dapat mengatur TMPDIRuntuk satu perintah - jika Anda memiliki direktori sementara yang biasa dalam sistem file RAM untuk kecepatan, Anda mungkin perlu melakukan ini untuk perintah yang menghasilkan file sementara besar (seperti raksasa sort, misalnya). Jangan abaikan standar / konvensi yang diharapkan pengguna Anda!
Toby Speight
Jelas memeriksa lingkungan untuk lokasi file sementara dan tidak pernah hard-code / tmp. Karena tmp bersama memiliki masalah keamanan, satu mitigasi yang sering saya lihat adalah membuat direktori per-pengguna / tmp tanpa izin baca-tulis untuk orang lain. Ini menghilangkan kemungkinan kondisi ras dan serangan symlink.
Zan Lynx
9

Direktori temp-file-sangat bergantung pada sistem / lingkungan. Misalnya dir web-server-temp terpisah dari os-temp-dir untuk alasan keamanan.

Di bawah ms-windows setiap pengguna memiliki temp-dir sendiri.

Anda harus menggunakan createTempFile () untuk ini jika fungsi seperti itu tersedia.

k3b
sumber
1
Berhati-hatilah dengan keterbatasan OS yang tersembunyi di Windows. Kami menemukan cara yang sulit bahwa jumlah maksimum file dalam folder dibatasi hingga 65.565. Tentu, itu banyak file, dan yakin, Anda seharusnya tidak pernah dibayangkan memiliki banyak peletakan di sekitar. Tapi apakah Anda yakin bahwa setiap aplikasi membersihkan dengan sendirinya secara tepat waktu dan berperilaku baik?
Mike Hofer
Ah, saya sudah melihat komentar Anda terlambat. Saya baru saja menulis yang sama di atas. BTW batasnya terutama disebabkan oleh mekanisme fungsi GetTimeFileName (), bukan NTFS. Batas folder yang Anda sebutkan hanya berlaku untuk FAT32 .
JensG
9

Jawaban sebelumnya, meskipun benar, tidak valid untuk sebagian besar cluster komputer skala besar.

Cluster komputer tidak selalu mengikuti konvensi standar untuk mesin, biasanya untuk alasan yang baik, dan tidak ada gunanya membahasnya dengan sysadmin.

Direktori Anda saat ini merujuk ke sistem file pusat, yang diakses melalui jaringan. Ini tidak hanya lambat, tetapi juga menempatkan banyak pada sistem untuk pengguna lainnya, jadi Anda tidak boleh menggunakannya kecuali Anda tidak banyak menulis dan Anda dapat memulihkannya jika pekerjaan macet.

Node komputasi memiliki hard drive sendiri, yaitu sistem file tercepat yang tersedia, dan apa yang seharusnya Anda gunakan. Dokumentasi klaster harus memberitahu Anda apa itu, biasanya /scratch, /tmp/[jobid]atau beberapa variabel lingkungan standar non ( $SNIC_TMPdi salah satu yang saya gunakan).

Jadi, apa yang saya rekomendasikan adalah membuatnya dapat dikonfigurasi pengguna. Default dapat menjadi yang pertama Anda memiliki akses tulis ke:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Tetapi mengharapkan tingkat keberhasilan yang rendah dengan pendekatan ini, dan pastikan untuk mengeluarkan peringatan besar.

Sunting: Saya akan menambahkan alasan lain untuk memaksanya diatur oleh pengguna. Salah satu kluster saya telah $TMPDIRditetapkan /scratch, yaitu dapat ditulis oleh pengguna dan pada hard drive lokal. Tetapi, dokumentasi mengatakan bahwa apa pun yang Anda tulis di luar /scratch/[jobid]dapat dihapus pada titik mana pun, bahkan di tengah jalan. Jadi, jika Anda mengikuti standar, dan kepercayaan $TMPDIR, Anda akan menemukan crash acak, sangat sulit untuk di-debug. Jadi, Anda mungkin menerima $TMPDIR, tetapi tidak mempercayainya.

Beberapa kluster lain memang memiliki variabel ini yang dikonfigurasi dengan benar, sehingga Anda dapat menambahkan opsi untuk mempercayai secara eksplisit $TMPDIR, jika tidak, berikan peringatan besar dan gemuk.

Davidmh
sumber
1
Yang mana tepatnya jawaban sebelumnya?
Tulains Córdova
2
Jadi yang Anda katakan di sini adalah bahwa karena beberapa kluster yang tidak mengambil langkah sepele untuk mematuhi standar yang sudah mapan untuk memberi tahu program tempat menulis file sementara mereka, itu adalah satu tambahan kustomisasi khusus klaster yang diperlukan per program. Teh yang cukup lemah jika kau bertanya padaku.
Blrfl
@ Blrfl Anda dapat melambaikan standar sebanyak yang Anda inginkan, dan menulis kode yang sesuai dengan mereka, dan selalu macet; Anda dapat mencoba bertarung dengan sysadmin dari setiap cluster yang Anda gunakan; atau Anda dapat menerima iman Anda dan membuatnya dapat dikonfigurasi. Plus, di HPC kita biasanya perlu mengadaptasi kode ke spesifikasi cluster (RAM yang tersedia, kecepatan relatif dari filesystem, implementasi MPI, ketersediaan sumber daya umum ...), tidak ada "satu ukuran cocok untuk semua".
Davidmh
@ Davidvidm: Dimengerti, tapi bukan itu intinya. Standar membuatnya dapat dikonfigurasi dengan cara yang tidak mencengangkan. Jika saya membawa kode sesuai-diketahui ke sebuah cluster di mana standar tidak diikuti, saya harus mengaturnya tepat di satu tempat, seperti di titik masuk. Satu hal yang kurang dalam sisa kode untuk diaudit, modifikasi, dan risiko kesalahan.
Blrfl
1

Untuk banyak aplikasi, Anda harus mempertimbangkan menempatkan file-file sementara di $XDG_RUNTIME_DIRatau $XDG_CACHE_HOME(dirs lainnya XDG adalah untuk file nontemporary). Untuk instruksi tentang penghitungan mereka jika mereka tidak diteruskan secara eksplisit di lingkungan, lihat spec berbasis XDG atau temukan perpustakaan yang sudah mengimplementasikan bagian itu.

Namun, perlu diketahui bahwa $XDG_RUNTIME_DIRitu merupakan tambahan baru dan tidak ada cadangan standar untuk sistem yang lebih lama karena masalah keamanan.

Jika tidak ada yang cocok, maka itu /tmpadalah tempat yang benar. Anda tidak boleh berasumsi direktori saat ini dapat ditulis.

o11c
sumber
-2

Ini lebih seperti alternatif, tetapi Anda dapat memutuskan tautan () file segera setelah fopen (). Itu tergantung dari pola penggunaan cource.

Membatalkan tautan file, jika dapat dilakukan, membantu untuk beberapa cara:

  • file tidak terlihat - pengguna tidak melihatnya.
  • file tidak terlihat dari proses lain - tidak ada kesempatan proses lain untuk memodifikasi file secara tidak sengaja.
  • pembersihan mudah jika program macet.

File harus dibuat di / tmp. Jika pengguna tidak memiliki hak untuk membuat file di sana, ini berarti sistem salah konfigurasi.

File tidak dapat dibuat di direktori home pengguna. Banyak pengguna, seperti "tidak ada", "www-data" dan banyak lainnya, tidak memiliki hak untuk menulis di direktori rumah mereka, atau mereka bahkan chroot () - red. Perhatikan bahwa bahkan di lingkungan chroot / tmp masih ada.

Nick
sumber
Meskipun ini mungkin ide yang bagus secara umum, itu tidak membantu para pengguna yang tidak memiliki izin menulis pada direktori tempat file tersebut dibuat.
5gon12eder
4
Itu juga tidak menjawab pertanyaan, di mana harus meletakkan file sementara.
Blrfl
Saya percaya jawaban saya entah bagaimana penting. Saya sudah mengedit, mungkin lebih jelas dengan cara ini.
Nick