Czy pliki tymczasowe powinny być zapisane w / tmp lub w bieżącym katalogu roboczym?

76

Mam program, który musi generować pliki tymczasowe. Jest napisany dla maszyn klastrowych.

Jeśli zapisałem te pliki w systemowym katalogu tymczasowym (np . /tmp:), niektórzy użytkownicy skarżyli się, że program się nie powiódł, ponieważ nie mieli odpowiedniego dostępu do / tmp. Ale jeśli zapisałem te pliki w katalogu roboczym, ci użytkownicy również narzekali, że nie chcą widzieć tych tajemniczych plików.

Która jest lepszą praktyką? Czy powinienem nalegać, aby oszczędzanie na /tmpto było właściwym podejściem i bronić każdej awarii jako „działającej zgodnie z przeznaczeniem” (tj. Poprosić administratora o odpowiednie pozwolenie / dostęp)?

SmallChess
źródło
3
sprawdź, czy program ma dostęp, a jeśli nie, znajdź innego temp dir
ratchet maniaka
24
Jeśli twój administrator spieprzył prawa dostępu, zdecydowanie powinien to naprawić. Co byś zrobił, gdyby Twój administrator zapomniał dodać prawa do wykonywania programu?
Doc Brown,
7
Nie znajdziesz / tmp w większości systemów Windows, ale istnieje wywołanie systemu operacyjnego, które powie ci, gdzie umieścić pliki tymczasowe.
Ian
28
Jeśli niektórzy ludzie nie mieli dostępu do /tmpsystemu uniksopodobnego, jest źle skonfigurowany. Administrator powinien zrobić coś takiego chmod 1777 /tmp.
musiphil
12
Uważaj, że $ TMPDIR może wskazywać inną ścieżkę niż /tmp/, której powinieneś użyć zamiast tego. Zobacz niektóre odpowiedzi;)
marcelm

Odpowiedzi:

141

Pliki tymczasowe muszą być przechowywane w katalogu tymczasowym systemu operacyjnego z kilku powodów:

  • System operacyjny bardzo ułatwia tworzenie tych plików, zapewniając jednocześnie, że ich nazwy będą unikalne .

  • Większość oprogramowania do tworzenia kopii zapasowych wie, jakie są katalogi zawierające pliki tymczasowe i pomija je. Jeśli korzystasz z bieżącego katalogu, może to mieć istotny wpływ na rozmiar przyrostowych kopii zapasowych, jeśli kopie zapasowe są wykonywane często.

  • Katalog tymczasowy może znajdować się na innym dysku lub w pamięci RAM, co znacznie przyspiesza dostęp do odczytu i zapisu .

  • Pliki tymczasowe są często usuwane podczas ponownego uruchamiania (jeśli znajdują się na ramdysku, są po prostu tracone). Zmniejsza to ryzyko nieskończonego wzrostu, jeśli aplikacja nie zawsze poprawnie usuwa pliki tymczasowe (na przykład po awarii).

    Czyszczenie plików tymczasowych z katalogu roboczego może łatwo popsuć się, jeśli pliki są przechowywane razem z plikami aplikacji i użytkownika. Możesz złagodzić ten problem, tworząc osobny katalog w bieżącym katalogu, ale może to prowadzić do innego problemu:

  • Długość ścieżki może być zbyt długo na niektórych platformach. Na przykład w systemie Windows limity ścieżek dla niektórych interfejsów API, ram i aplikacji są straszne , co oznacza, że ​​możesz łatwo przekroczyć taki limit, jeśli bieżący katalog jest już głęboko w hierarchii drzewa, a nazwy plików tymczasowych są zbyt długie.

  • Na serwerach często monitoruje się wzrost katalogu tymczasowego . Jeśli użyjesz innego katalogu, może nie być monitorowany, a monitorowanie całego dysku nie pomoże łatwo stwierdzić, że to pliki tymczasowe zajmują coraz więcej miejsca.

Jeśli chodzi o błędy odmowy dostępu, upewnij się, że system operacyjny utworzył dla ciebie plik tymczasowy. System operacyjny może na przykład wiedzieć, że dla danego użytkownika należy użyć katalogu innego niż /tmplub C:\Windows\temppowinien; w ten sposób, uzyskując bezpośredni dostęp do tych katalogów, możesz rzeczywiście napotkać błąd odmowy dostępu.

Jeśli dostaniesz odmowę dostępu nawet podczas korzystania z wywołania systemu operacyjnego, cóż, oznacza to po prostu, że komputer był źle skonfigurowany; zostało to już wyjaśnione przez Blrfl . Konfiguracja systemu zależy od administratora systemu; nie musisz zmieniać swojej aplikacji.

Tworzenie plików tymczasowych jest proste w wielu językach. Kilka przykładów:

  • Grzmotnąć:

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

    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!");
    
  • DO#:

    // 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);
    
  • Rubin:

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

Zauważ, że w niektórych przypadkach, takich jak PHP i Ruby, plik jest usuwany po zamknięciu uchwytu. To dodatkowa zaleta korzystania z bibliotek dołączonych do języka / frameworka.

Arseni Mourzenko
źródło
2
Co rozumiesz przez „upewnij się, że system operacyjny utworzy dla ciebie plik tymczasowy”. Więc zamiast np. fopen("/tmp/mytmpfile", "w");Powinienem wykonać jakieś wywołanie systemowe do obsługi plików tymczasowych?
simon
30
@gurka: Powinieneś dzwonić w tmpfile(3)celu wygenerowania plików tymczasowych lub przynajmniej dzwonić w mktemp(3)celu utworzenia nazw plików.
TMN
3
@TMN: Są to po prostu funkcje biblioteczne działające w przestrzeni użytkownika i nie mają żadnej magii, by ominąć błąd uprawnień podany przez system operacyjny.
musiphil
25
@musiphil Zarówno tmpfile, jak i mktemp używają zmiennych zewnętrznych do określenia ścieżki dla plików tymczasowych. Mogą być skonfigurowane tak, aby wskazywały na inny katalog niż / tmp /, być może katalog na użytkownika. Próba ręcznego utworzenia nazwy pliku w / tmp / może się nie powieść, podczas gdy tmpfile i mktemp zwrócą prawidłowe ścieżki.
rura
2
@musiphil: Nigdy nie mówiłem, że naprawią problem z uprawnieniami, odpowiadałem na jego pytanie dotyczące używania wywołań systemowych do tworzenia plików.
TMN
33

Czy powinienem nalegać, aby zapisywanie w / tmp było właściwym podejściem i bronić się przed każdą awarią jako „działającą zgodnie z przeznaczeniem” (tj. Poprosić administratora o odpowiedni dostęp do uprawnień)?

Istnieją w tym standardy, a najlepsze, co możesz zrobić, to dostosować się do nich.

POSIX, po którym następuje prawie każdy system operacyjny inny niż mainframe o dowolnym znaczeniu, na który prawdopodobnie natkniesz się, ma przepisy dotyczące tworzenia plików tymczasowych o niepowtarzalnych nazwach w katalogu przy użyciu wartości domyślnych, które środowisko może ponownie skonfigurować:

  • stdio.hNagłówek C może opcjonalnie zawierać P_tmpdirmakro określające katalog tymczasowy systemu.
  • TMPDIRjest kanoniczną zmienną środowiskową do zmiany lokalizacji plików tymczasowych. Przed POSIX, były stosowane inne zmienne, więc staram się iść z pierwszą tego czy TMP, TEMPDIRi TEMPże ma wartość, popływać i korzystania z domyślnego systemu, jeśli żadna z tych istnieje.
  • Funkcje mkstemp()i tempfile()wygenerują unikalne pliki tymczasowe.

Jeśli twoim użytkownikom odmawia się możliwości tworzenia plików tymczasowych, system jest źle skonfigurowany lub administratorzy nie wyjaśniają, jakie są ich zasady dotyczące takich rzeczy. W takich przypadkach byłbyś bardzo pewny, mówiąc, że twój program jest zgodny z dobrze ustalonym standardem przenośności i że jego zachowanie można zmienić za pomocą zmiennych środowiskowych określonych przez standard.

Blrfl
źródło
P_tmpdirnie jest częścią stdio.hzgodnie ze specyfikacją języka C. Może być zdefiniowany przez POSIX lub SVID.
musiphil
1
@musiphil: Jak sugeruje (teraz wyjaśniona) odpowiedź, jest ona częścią POSIX. (Technicznie rzecz biorąc, jest to rozszerzenie systemu X / Open, które zostało włączone przez POSIX. Zobacz pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl
Całkowicie zgadzam się ze wszystkimi powyższymi. Dobrym przykładem jest Linux z pam_tmpdir- to ustawia TMPDIRi TMPbyć różna dla każdego użytkownika, dla solidności i prywatności. Przydaje się również możliwość ustawienia TMPDIRdla pojedynczego polecenia - jeśli masz zwykły katalog tymczasowy w systemie plików RAM dla szybkości, być może będziesz musiał to zrobić dla poleceń, które generują ogromne pliki tymczasowe (na przykład gigantyczny sort). Nie ignoruj ​​standardów / konwencji, których oczekują Twoi użytkownicy!
Toby Speight
Zdecydowanie sprawdź środowisko pod kątem lokalizacji plików tymczasowych i nigdy nie twórz kodu / tmp. Ponieważ współużytkowane tmp ma problemy z bezpieczeństwem, jednym z często spotykanych przeze mnie problemów jest tworzenie katalogów na użytkownika / tmp bez uprawnień do odczytu i zapisu dla innych osób. Usuwa możliwe warunki wyścigu i ataki z użyciem dowiązań symbolicznych.
Zan Lynx,
9

Katalog plików tymczasowych jest wysoce zależny od systemu operacyjnego / środowiska. Na przykład ze względów bezpieczeństwa katalog serwerów-temp-temp jest oddzielony od katalogu os-temp-katalog.

Pod ms-windows każdy użytkownik ma swój własny temp-katalog.

w tym celu należy użyć metody createTempFile (), jeśli taka funkcja jest dostępna.

k3b
źródło
1
Pamiętaj tylko o ukrytych ograniczeniach systemu operacyjnego w systemie Windows. Odkryliśmy, że maksymalna liczba plików w folderze była ograniczona do 65 565. Pewnie, że jest wiele plików, a na pewno, nigdy nie powinno conceivably mieć, że wielu r dookoła. Ale czy jesteś pewien, że każda aplikacja czyści po sobie w odpowiednim czasie i dobrze się zachowuje?
Mike Hofer,
Ach, widziałem twój komentarz za późno. Właśnie napisałem to samo powyżej. BTW limit wynika przede wszystkim z mechaniki funkcji GetTimeFileName (), a nie NTFS. Wspomniany limit folderów dotyczy tylko FAT32 .
JensG,
9

Poprzednie odpowiedzi, choć poprawne, nie są poprawne dla większości klastrów komputerowych na dużą skalę.

Klastry komputerowe nie zawsze przestrzegają standardowych konwencji dla maszyn, zwykle z dobrych powodów, i nie ma sensu dyskutować o tym z administratorami.

Twój bieżący katalog odnosi się do centralnego systemu plików, do którego dostęp jest uzyskiwany przez sieć. Jest to nie tylko wolne, ale także nakłada obciążenia na system dla reszty użytkowników, więc nie powinieneś go używać, chyba że nie piszesz dużo i możesz odzyskać od niego, jeśli zadanie się zawiesi.

Węzły obliczeniowe mają własny dysk twardy, czyli najszybszy dostępny system plików i to, czego powinieneś używać. Dokumentacja klaster powinien powiedzieć, co to jest, typowo /scratch, /tmp/[jobid]lub niektóre niestandardowe zmienne środowisko ( $SNIC_TMPw jednym z tych, których używam).

Dlatego zalecam skonfigurowanie go przez użytkownika. Domyślne wartości mogą być pierwszymi, do których masz dostęp do zapisu:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Ale spodziewaj się niskiego wskaźnika sukcesu z tym podejściem i upewnij się, że wyślesz duże ostrzeżenie o tłuszczu.

Edycja: dodam kolejny powód, aby wymusić ustawienie użytkownika. Jeden z moich klastrów jest $TMPDIRustawiony na /scratchopcję zapisu przez użytkownika na lokalnym dysku twardym. Ale dokumentacja mówi, że wszystko, co piszesz poza, /scratch/[jobid]może zostać usunięte w dowolnym momencie, nawet w połowie cyklu. Jeśli więc przestrzegasz standardów i $TMPDIRmasz zaufanie , napotkasz przypadkowe awarie, bardzo trudne do debugowania. Możesz więc zaakceptować $TMPDIR, ale nie ufać.

Niektóre inne klastry mają poprawnie skonfigurowaną tę zmienną, więc możesz dodać opcję jawnego zaufania $TMPDIR, w przeciwnym razie wyślesz duże, grube ostrzeżenie.

Davidmh
źródło
1
Które dokładnie są poprzednimi odpowiedziami?
Tulains Córdova,
2
Mówisz tutaj, że ponieważ niektóre klastry, które nie wykonują banalnego kroku polegającego na przestrzeganiu ustalonego standardu informowania programów, gdzie mają zapisywać pliki tymczasowe, jest to jedno dodatkowe dostosowanie specyficzne dla klastra dla każdego programu. Dość słaba herbata, jeśli mnie zapytasz.
Blrfl,
@Blrfl możesz falować standardy tyle, ile chcesz, i pisać kod, który jest im idealnie zgodny i zawsze ulega awarii; możesz spróbować walczyć z administratorami każdego używanego klastra; lub możesz zaakceptować swoją wiarę i uczynić ją konfigurowalną. Ponadto w HPC zwykle trzeba i tak dostosować kod do specyfiki klastra (dostępna pamięć RAM, względna szybkość systemów plików, implementacja MPI, ogólna dostępność zasobów ...), nie ma „jednego rozmiaru dla wszystkich”.
Davidmh,
@Davidmh: Zrozumiałem, ale nie o to chodzi. Standard sprawia, że ​​można go konfigurować w nie zaskakujący sposób. Jeśli zabiorę znany kod do klastra, w którym standard nie jest przestrzegany, muszę ustawić go dokładnie w jednym miejscu, na przykład w punkcie wejścia. W pozostałej części kodu jest to jedna mniejsza rzecz do kontrolowania, modyfikowania i ryzyka popełnienia błędu.
Blrfl,
1

W przypadku wielu aplikacji należy rozważyć umieszczenie plików tymczasowych w $XDG_RUNTIME_DIRlub $XDG_CACHE_HOME(inne katalogi XDG dotyczą plików innych niż współczesne). Instrukcje dotyczące ich obliczania, jeśli nie są jawnie przekazywane w środowisku, zobacz specyfikację opartą na XDG lub znajdź bibliotekę, która już implementuje tę część.

Należy jednak pamiętać, że $XDG_RUNTIME_DIRjest to nowy dodatek i nie ma standardowego powrotu do starszych systemów ze względów bezpieczeństwa.

Jeśli żadne z nich nie jest odpowiednie, to /tmpjest właściwe miejsce. Nigdy nie należy zakładać, że bieżący katalog jest zapisywalny.

o11c
źródło
-2

To jest bardziej jak alternatywa, ale możesz odłączyć () plik natychmiast po fopen (). Zależy to od wzorca użytkowania.

Odłączenie plików, jeśli można to zrobić, pomaga na kilka sposobów:

  • plik nie jest widoczny - użytkownik go nie widzi.
  • plik nie jest widoczny z innych procesów - nie ma szans, aby inny proces zmodyfikował plik przez pomyłkę.
  • łatwe czyszczenie w przypadku awarii programu.

Pliki należy utworzyć w / tmp. Jeśli użytkownik nie ma uprawnień do utworzenia pliku, oznacza to, że system jest źle skonfigurowany.

Pliki nie mogą być tworzone w katalogu domowym użytkowników. Wielu użytkowników, takich jak „nikt”, „dane www” i wielu innych, nie ma prawa pisać w swoich katalogach domowych, a nawet są chroot () - red. Zauważ, że nawet w środowisku chroot / tmp nadal istnieje.

Nacięcie
źródło
Chociaż może to być dobry pomysł, nie pomaga użytkownikom, którzy nie mają uprawnień do zapisu w katalogu, w którym ma zostać utworzony plik.
5gon12eder
4
Nie odpowiada również na pytanie, gdzie umieścić tymczasowe pliki.
Blrfl,
Wierzę, że moja odpowiedź jest jakoś ważna. Zrobiłem edycję, prawdopodobnie jest to bardziej przejrzyste w ten sposób.
Nick