Geçici dosyalar / tmp'a veya mevcut çalışma dizinine kaydedilmeli mi?


76

Geçici dosyalar üretmek için gereken bir programım var. Küme makinaları için yazılmıştır.

Bu dosyaları sistem genelindeki geçici bir dizine (örneğin:) kaydettiyseniz /tmp, bazı kullanıcılar / tmp dizinine uygun erişimi olmadığından programın başarısız olduğundan şikayet ettiler. Ancak bu dosyaları çalışma dizinine kaydettiyseniz, bu kullanıcılar da gizemli dosyaları görmek istemediklerinden şikayetçi oldular.

Hangisi daha iyi bir uygulamadır? Tasarruf /tmpetmenin doğru bir yaklaşım olduğu konusunda ısrarlı olmalı mıyım ve herhangi bir hatayı "istenildiği gibi çalış" olarak savunmalı mıyım (yani, yöneticinizden uygun izin / erişim isteyin)?


3
Programın erişip
kilit manyağı

24
Yöneticiniz erişim haklarını bozduysa, kesinlikle düzeltmesi gerekir. Yöneticiniz programınıza uygulama hakları eklemeyi unutmuşsa ne yapardınız?
Doktor Brown

7
Çoğu Windows sistemde bulamazsınız / tmp, ancak geçici dosyaları nereye koyacağınızı söyleyen bir işletim sistemi çağrısı vardır.
Ian

28
Bazı insanlar /tmpUnix benzeri bir sisteme erişemedilerse , yanlış yapılandırılmış. Süper kullanıcı gibi bir şey yapmalı chmod 1777 /tmp.
musiphil

12
$ TMPDIR uygulamasının /tmp/kullanmanız gerekenden farklı bir yolu gösterebileceğini unutmayın. Cevapların bazılarına bakınız;)
marcelm

Yanıtlar:


141

Geçici dosyaların çeşitli nedenlerden dolayı işletim sistemi geçici dizinine kaydedilmesi gerekir:

  • İşletim sistemi, adlarının benzersiz olmasını sağlarken bu dosyaları oluşturmayı çok kolaylaştırır .

  • Çoğu yedekleme yazılımı, geçici dosyaları içeren dizinlerin ne olduğunu bilir ve bunları atlar. Geçerli dizini kullanırsanız, yedekleme sık sık yapılırsa , artımlı yedeklemelerin boyutu üzerinde önemli bir etkisi olabilir .

  • Geçici dizin okuma-yazma erişimini çok daha hızlı hale getiren farklı bir diskte veya RAM'de olabilir .

  • Geçici dosyalar, yeniden başlatma sırasında sık sık silinir (eğer bir ramdisk içindeyse basitçe kaybolurlar). Bu , uygulamanızın geçici dosyaları her zaman doğru şekilde kaldırmıyorsa (örneğin bir çökmeden sonra) , sonsuz büyüme riskini azaltır .

    Dosyalar uygulama ve kullanıcı dosyalarıyla birlikte depolanırsa geçici dosyaların çalışma dizininden temizlenmesi kolayca karışabilir. Geçerli dizinde ayrı bir dizin oluşturarak bu sorunu azaltabilirsiniz, ancak bu başka bir soruna yol açabilir:

  • Yol uzunluğu bazı platformlarda çok uzun olabilir. Örneğin, Windows'ta, bazı API'ler, çerçeveler ve uygulamalar için yol sınırları korkunçtur ; bu, geçerli dizin ağaç hiyerarşisinde zaten derinse ve geçici dosyalarınızın adlarının çok uzun olması durumunda bu sınıra kolayca erişebileceğiniz anlamına gelir.

  • Sunucularda geçici dizinin büyümesinin izlenmesi genellikle hemen yapılır. Farklı bir dizin kullanırsanız, izlenmeyebilir ve tüm diskin izlenmesi, gittikçe daha fazla yer tutan geçici dosyalar olduğunu kolayca anlamaya yardımcı olmaz.

Erişim reddedilen hatalara gelince, işletim sisteminin sizin için geçici bir dosya oluşturmasına izin verdiğinizden emin olun. İşletim sistemi, örneğin, belirli bir kullanıcı, daha başka bir dizin için biliyor olabilir /tmpya da C:\Windows\tempkullanılmalıdır; bu nedenle, bu dizinlere doğrudan erişerek, gerçekten bir erişim reddi hatasıyla karşılaşabilirsiniz.

İşletim sistemi çağrısı kullanılırken bile erişiminiz reddedilirse, bu makinenin kötü bir şekilde yapılandırıldığı anlamına gelir; bu zaten Blrfl tarafından açıklanmıştır . Makineyi yapılandırmak sistem yöneticisine kalmıştır; başvurunuzu değiştirmek zorunda değilsiniz.

Geçici dosyalar oluşturmak birçok dilde basittir. Birkaç örnek:

  • Bash:

    # 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);
  • Yakut:

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

PHP ve Ruby gibi bazı durumlarda, tanıtıcı kapatıldığında dosyanın kaldırıldığını unutmayın. Bu, dil / çerçeve ile birlikte verilen kütüphaneleri kullanmanın ek bir yararıdır.


2
"İşletim sisteminin sizin için geçici bir dosya oluşturmasına izin verdiğinizden emin olun" derken ne demek istiyorsunuz? Öyleyse örneğin fopen("/tmp/mytmpfile", "w");geçici dosyaları işlemek için bazı sistem çağrıları yapmalı mıyım?
simon,

30
@gurka: tmpfile(3)Geçici dosyalarınızı oluşturmak için ya da en azından mktemp(3)dosya adlarını oluşturmak için çağrı yapıyor olmalısınız .
TMN

3
@TMN: Yalnızca kullanıcı alanında çalışan kütüphane işlevleridir ve işletim sistemi tarafından verilen izin hatasını atlamak için herhangi bir sihirleri yoktur.
musiphil

25
@ musiphil Hem tmpfile hem de mktemp, geçici dosyaların yolunu belirlemek için harici değişkenleri kullanır. Bunlar / tmp / dizininden başka bir dizini, belki de kullanıcı başına bir dizini gösterecek şekilde ayarlanmış olabilir. / Tmp / içinde bir dosya adı manüel olarak oluşturmaya çalışmak başarısız olabilir, tmpfile ve mktemp geçerli yollar döndürür.
pipo

2
@ musiphil: İzin problemini çözeceklerini asla söylemedim, dosyaları oluşturmak için sistem çağrılarını kullanma konusundaki sorusuna cevap veriyordum.
TMN

33

/ Tmp'a kaydetmekte ısrar etmem gerekir mi ve "amaçlandığı gibi çalışmak" gibi herhangi bir hatayı savunmak mı istiyorsunuz (ör. Yöneticinizden uygun izin erişimi isteyin)?

Bunun için standartlar var ve yapabileceğiniz en iyi şey bunlara uymak.

Ana bilgisayar olmayan hemen hemen her bir öneme sahip olan işletim sistemi tarafından takip edilen POSIX'in, muhtemelen sizin tarafından değiştirilebilecek varsayılan değerleri kullanarak, bir dizinde benzersiz olarak adlandırılmış geçici dosyalar oluşturma hükümleri vardır:

  • C stdio.hbaşlığı isteğe bağlı P_tmpdirolarak sistemin geçici dizinini adlandıran bir makro içerebilir .
  • TMPDIRgeçici dosyaların konumunu değiştirmek için kullanılan kanonik ortam değişkenidir. POSIX'e önce kullanılan diğer değişkenler vardı, bu yüzden o ya ilkine gitme eğilimi TMP, TEMPDIRve TEMPo punting ve bunlardan herhangi bir şey yoksa varsayılan sistem kullanılarak, bir değeri vardır.
  • mkstemp()Ve tempfile()işlevleri benzersiz geçici dosyaları oluşturur.

Kullanıcılarınızın geçici dosyalar oluşturma kabiliyetleri reddedilirse, sistem ya yanlış bir şekilde yapılandırılır ya da yöneticiler politikalarının bu gibi şeylerde ne olduğunu netleştirmezler. Bu gibi durumlarda, programınızın sağlam bir taşınabilirlik standardına uygun olduğunu ve davranışının standardın belirttiği ortam değişkenleri kullanılarak değiştirilebileceğini söyleyerek çok katı olacaksınız.


P_tmpdirstdio.hC dili belirtiminde tanımlandığı şekilde değildir . POSIX veya SVID tarafından tanımlanabilir.
musiphil

1
@ musiphil: (Şimdi açıklığa kavuşturulmuş) cevabının ima ettiği gibi, POSIX'in bir parçasıdır. (Teknik olarak dahil POSIX bir X / Open Sistem Uzantısı var bakın. Pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl

Yukarıdakilerin tümüne tamamen katılıyorum. Bunun güzel bir örneği Linux sistemleridir pam_tmpdir- bu ayarlar TMPDIRve TMPher kullanıcı için sağlamlık ve mahremiyet için farklı olmak. TMPDIRTek bir komut ayarlayabilmeniz de yararlıdır - olağan geçici dizininizi bir RAM dosya sisteminde hız için kullanıyorsanız, bunu büyük geçici dosyalar (örneğin, bir dev gibi) üreten komutlar için yapmanız gerekebilir sort. Kullanıcılarınızın beklediği standartları / kuralları göz ardı etmeyin!
Toby Speight

Ortamın geçici dosyaların konumu ve kesinlikle sabit kod / tmp olup olmadığını kontrol edin. Paylaşılan bir tmp'nin güvenlik sorunları olduğundan, sık sık gördüğüm bir azaltma, başkaları için okuma-yazma izni olmayan kullanıcı başına / tmp dizinleri oluşturmaktır. Olası yarış koşullarını ve sembolik bağlantı saldırılarını kaldırır.
Zan Lynx

9

Temp-file-dizini yüksek işletim sistemine / ortama bağlıdır. Örneğin bir web-server-temp dir, güvenlik nedeniyle os-temp-dir'den ayrıdır.

Ms-windows altında her kullanıcının kendi temp-dir'i vardır.

Böyle bir işlev varsa bunun için createTempFile () kullanmanız gerekir .


1
Windows'ta gizli işletim sistemi sınırlamalarına dikkat edin. Bir klasördeki maksimum dosya sayısının 65.565 ile sınırlı olduğunu zor yoldan keşfettik. Tabii, bu dosyaların bir çok şey var ve tabii, asla makul sayıda etrafında döşeme olduğunu var. Ancak, her uygulamanın kendisinden sonra zamanında ve iyi davranış gösteren bir şekilde temizlediğinden emin misin ?
Mike Hofer

Ah, yorumunuzu çok geç gördüm. Ben de aynısını yukarıda yazdım. BTW sınırı, öncelikle NTFS değil GetTimeFileName () işlevinin tekniğinden kaynaklanmaktadır. Bahsettiğiniz klasör sınırı sadece FAT32 için geçerlidir .
JensG

9

Önceki cevaplar, doğru olmasına rağmen, çoğu büyük ölçekli bilgisayar kümesi için geçerli değildir.

Bilgisayar kümeleri her zaman makineler için standart kuralları her zaman takip etmiyor, genellikle iyi nedenlerle ve sistem yöneticileriyle tartışmanın bir anlamı yok.

Geçerli dizininiz, ağ üzerinden erişilen merkezi dosya sistemine atıfta bulunuyor. Bu sadece yavaş değil, aynı zamanda kullanıcıların geri kalanı için de sisteme yükler yüklüyor, bu yüzden fazla yazmadığınız ve iş çöktüğünde kurtaramadığınız sürece kullanmamanız gerekir.

Bilgi işlem düğümlerinin kendi sabit diskleri var; bu, mevcut en hızlı dosya sistemi ve ne kullanmanız gerektiğidir. Küme dokümantasyon genellikle, ne olduğunu söylemelidir /scratch, /tmp/[jobid]ya (bazı standart olmayan çevre değişkeni $SNIC_TMPkullandığım olanlar birinde).

Yani, önerdiğim şey onu kullanıcı tarafından yapılandırılabilir hale getirmek. Varsayılanlar, yazma hakkınız olan ilk kişi olabilir:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Ancak bu yaklaşımla düşük bir başarı oranı bekleyin ve büyük bir yağ uyarısı verdiğinizden emin olun.

Düzenleme: Kullanıcı tarafından ayarlanması için başka bir sebep ekleyeceğim. Benim kümelerden biri olan $TMPDIRayarlı /scratch, o kullanıcı yazılabilir ve yerel sabit diske. Ancak, belgeler dışına yazdığınız her şeyin /scratch/[jobid], çalışmanın ortasında bile olsa herhangi bir noktada silinebileceğini söylüyor . Bu nedenle, standartları uygularsanız ve güvenirseniz $TMPDIR, hata ayıklamak çok zor olan rastgele kazalarla karşılaşırsınız. Öyleyse kabul edebilirsin $TMPDIR, ama güvenmiyorsun.

Diğer bazı kümeler bu değişkeni uygun şekilde yapılandırmıştır, bu nedenle açıkça güvenmek için bir seçenek ekleyebilirsiniz $TMPDIR, aksi halde büyük, yağ uyarısı verir.


1
Önceki cevaplar tam olarak hangileri?
Tulains Córdova 06.06.2016

2
Öyleyse burada söylediğiniz şey, programların geçici dosyalarını nereye yazacaklarını söylemek için köklü bir standarda bağlı kalmanın önemsiz adımlarını atmayan bazı kümelerin program başına gereken bir kümeye özgü özelleştirme olması. Bana sorarsan oldukça zayıf çay.
Blrfl

@Blrfl, standartları istediğiniz kadar sallandırabilir ve bunlara mükemmel şekilde uyan ve her zaman kilitlenen bir kod yazabilirsiniz; kullandığınız her kümenin sistem yöneticileriyle savaşmayı deneyebilirsiniz; veya inancınızı kabul edip yapılandırılabilir hale getirebilirsiniz. Ayrıca, HPC'de genellikle bir kodun kümenin özelliklerine zaten uyarlanması gerekir (mevcut RAM, dosya sistemlerinin nispi hızı, MPI uygulaması, kaynakların genel kullanılabilirliği ...), "tek bir boyuta uymuyor" yoktur.
Davidmh

@Davidmh: Anlaşıldı, ama mesele değil. Standart , şaşırtıcı olmayan bir şekilde yapılandırılabilir hale getirir . Bilinen uygunluk kodunu standardın takip edilmediği bir kümeye götürürsem , giriş noktası gibi tam olarak bir yere yerleştirmem gerekir . Bu kodun geri kalanında denetleme, değiştirme ve yanlış risk alma riskinden daha az bir şeydir.
Blrfl

1

Birçok uygulama için, geçici dosyaları $XDG_RUNTIME_DIRveya içine koymayı düşünmelisiniz $XDG_CACHE_HOME(diğer XDG dizinleri güncel olmayan dosyalar içindir). Ortamda açıkça geçirilmezlerse, bunların hesaplanmasına ilişkin talimatlar için , XDG basedir spec'e bakın veya bu bölümü zaten uygulayan bir kütüphane bulun.

Bununla birlikte, bunun $XDG_RUNTIME_DIRyeni bir ekleme olduğunu ve güvenlik endişelerinden dolayı eski sistemler için standart bir geri dönüş olmadığını unutmayın.

Bunlardan hiçbiri uygun değilse, o zaman /tmpdoğru yer. Sen gerektiğini asla geçerli dizin yazılabilir olduğunu varsayalım.


-2

Bu bir alternatif gibi, ancak fopen () 'dan hemen sonra dosyanın bağlantısını kesebilir (). Nezaket kullanım şekline bağlıdır.

Dosyaların bağlantısını kaldırmak, yapılabiliyorsa, birkaç yol için yardımcı olur:

  • dosya görünmüyor - kullanıcı göremiyor.
  • dosya diğer işlemlerden görülmez - dosyayı başka bir işlemle yanlışlıkla değiştirme şansı yoktur.
  • program çökmesi halinde kolay temizleme.

Dosyalar / tmp içinde oluşturulmalıdır. Kullanıcının orada dosya oluşturma hakkı yoksa, bu, sistemin yanlış yapılandırıldığı anlamına gelir.

Kullanıcılar ana dizinde dosyalar oluşturulamaz. "Hiç kimse", "www-data" ve diğerleri gibi pek çok kullanıcı, kendi dizinlerine yazma haklarına sahip değiller veya hatta chroot (). Chroot ortamında bile / tmp hala var olduğuna dikkat edin.


Bu, genel olarak iyi bir fikir olsa da, dosyanın oluşturulacağı dizinde yazma izni olmayan kullanıcılara yardımcı olmaz.
5gon12eder

4
Ayrıca geçici dosyaların nereye konacağı sorusuna cevap vermiyor.
Blrfl

Cevabımın bir şekilde önemli olduğuna inanıyorum. Düzenledim, muhtemelen bu şekilde daha açık.
Nick
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.