I file temporanei devono essere salvati in / tmp o nella directory di lavoro corrente?


76

Ho un programma che deve generare file temporanei. È scritto per macchine a grappolo.

Se ho salvato quei file in una directory temporanea a livello di sistema (ad esempio:) /tmp, alcuni utenti si sono lamentati del fallimento del programma perché non avevano un accesso adeguato a / tmp. Ma se salvassi quei file nella directory di lavoro, quegli utenti si lamentavano anche di non voler vedere quei file misteriosi.

Quale è una pratica migliore? Devo insistere sul fatto che il salvataggio /tmpè l'approccio giusto e difendere qualsiasi errore come "funzionante come previsto" (es. Chiedere al proprio amministratore l'autorizzazione / accesso corretti)?


3
controlla se il programma ha accesso e, in caso contrario, trova un altro
mostro indiretto

24
Se il tuo amministratore ha rovinato i diritti di accesso, dovrebbe sicuramente risolverlo. Cosa faresti se il tuo amministratore dimenticasse di aggiungere i diritti di esecuzione al tuo programma?
Doc Brown,

7
Non troverai / tmp sulla maggior parte dei sistemi Windows, ma c'è una chiamata del sistema operativo che ti dirà dove mettere i file temporanei.
Ian,

28
Se alcune persone non avevano accesso a /tmpun sistema simile a Unix, è configurato in modo errato. Il superutente dovrebbe fare qualcosa del genere chmod 1777 /tmp.
musiphil,

12
Fai attenzione che $ TMPDIR potrebbe puntare a un percorso diverso da quello /tmp/che dovresti invece utilizzare. Vedi alcune delle risposte;)
marcelm

Risposte:


141

I file temporanei devono essere archiviati nella directory temporanea del sistema operativo per diversi motivi:

  • Il sistema operativo semplifica la creazione di tali file garantendo al contempo che i loro nomi siano univoci .

  • La maggior parte dei software di backup sa quali sono le directory che contengono file temporanei e le salta. Se si utilizza la directory corrente, potrebbe avere un effetto importante sulla dimensione dei backup incrementali se i backup vengono eseguiti frequentemente.

  • La directory temporanea può trovarsi su un altro disco o nella RAM, rendendo l' accesso in lettura e scrittura molto, molto più veloce .

  • I file temporanei vengono spesso eliminati durante il riavvio (se si trovano in un ramdisk, vengono semplicemente persi). Ciò riduce il rischio di crescita infinita se l'app non rimuove sempre correttamente i file temporanei (ad esempio dopo un arresto anomalo).

    La pulizia dei file temporanei dalla directory di lavoro potrebbe diventare facilmente disordinata se i file vengono archiviati insieme ai file dell'applicazione e dell'utente. È possibile mitigare questo problema creando una directory separata all'interno della directory corrente, ma ciò potrebbe causare un altro problema:

  • La lunghezza del percorso potrebbe essere troppo lunga su alcune piattaforme. Ad esempio, su Windows, i limiti di percorso per alcune API, framework e applicazioni sono terribili , il che significa che puoi facilmente raggiungere tale limite se la directory corrente è già profonda nella gerarchia dell'albero e i nomi dei tuoi file temporanei sono troppo lunghi.

  • Sui server, il monitoraggio della crescita della directory temporanea viene spesso eseguito immediatamente. Se si utilizza una directory diversa, potrebbe non essere monitorato e il monitoraggio dell'intero disco non aiuterà a capire facilmente che sono i file temporanei che occupano sempre più spazio.

Per quanto riguarda gli errori di accesso negato, assicurati di consentire al sistema operativo di creare un file temporaneo per te. Il sistema operativo può, ad esempio, sapere che per un determinato utente deve essere utilizzata una directory diversa da /tmpo C:\Windows\temp; pertanto, accedendo direttamente a queste directory, potresti effettivamente riscontrare un errore di accesso negato.

Se si ottiene un accesso negato anche quando si utilizza la chiamata del sistema operativo, significa semplicemente che la macchina è stata configurata male; questo è già stato spiegato da Blrfl . Spetta all'amministratore di sistema configurare la macchina; non è necessario modificare l'applicazione.

La creazione di file temporanei è semplice in molte lingue. Alcuni esempi:

  • bash:

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

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

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

Si noti che in alcuni casi, come in PHP e Ruby, il file viene rimosso quando viene chiuso l'handle. Questo è un ulteriore vantaggio dell'utilizzo delle librerie in bundle con il linguaggio / framework.


2
Cosa intendi con "assicurati di consentire al sistema operativo di creare un file temporaneo per te". Quindi, invece di es fopen("/tmp/mytmpfile", "w");. Dovrei fare qualche chiamata di sistema per gestire i file temporanei?
simon,

30
@gurka: dovresti chiamare tmpfile(3)per generare i tuoi file temporanei, o almeno chiamare mktemp(3)per creare i nomi dei file.
TMN,

3
@TMN: sono solo funzioni di libreria che vengono eseguite nello spazio utente e non hanno alcuna magia per aggirare l'errore di autorizzazione fornito dal sistema operativo.
musiphil,

25
@musiphil Sia tmpfile che mktemp utilizzano variabili esterne per determinare il percorso dei file temporanei. Questi potrebbero essere stati impostati per puntare a un'altra directory diversa da / tmp /, forse una directory per utente. Il tentativo di creare manualmente un nome file in / tmp / potrebbe non riuscire, mentre tmpfile e mktemp restituirebbero percorsi validi.
pipe

2
@musiphil: non ho mai detto che avrebbero risolto il problema dei permessi, stavo rispondendo alla sua domanda sull'uso delle chiamate di sistema per creare i file.
TMN,

33

Devo insistere sul fatto che il salvataggio in / tmp sia l'approccio giusto e difendere qualsiasi errore come "funzionante come previsto" (ad es. Chiedere al proprio amministratore di accedere correttamente alle autorizzazioni)?

Ci sono standard per questo e la cosa migliore che puoi fare è conformarti a loro.

POSIX, che è seguito praticamente da tutti i sistemi operativi non mainframe di qualsiasi significato che si verifichino, ha disposizioni per la creazione di file temporanei con nomi univoci in una directory utilizzando valori predefiniti che possono essere riconfigurati dall'ambiente:

  • L' stdio.hintestazione C può eventualmente includere una P_tmpdirmacro che denomina la directory temporanea del sistema.
  • TMPDIRè la variabile di ambiente canonica per modificare la posizione dei file temporanei. Prima di POSIX, c'erano altre variabili utilizzate, quindi tendo ad andare con la prima di quella o TMP, TEMPDIRe TEMPche ha un valore, puntando e usando l'impostazione predefinita del sistema se nessuna di queste esiste.
  • Le funzioni mkstemp()e tempfile()genereranno file temporanei univoci.

Se agli utenti viene negata la possibilità di creare file temporanei, il sistema è configurato in modo errato o gli amministratori non stanno chiarendo quale sia la loro politica su tali aspetti. In questi casi, saresti su una base molto ferma nel dire che il tuo programma è conforme a uno standard di portabilità ben consolidato e che il suo comportamento può essere modificato usando le variabili di ambiente specificate dallo standard.


P_tmpdirnon fa parte di stdio.hcome definito dalla specifica del linguaggio C. Potrebbe essere definito da POSIX o SVID.
musiphil,

1
@musiphil: come implica la risposta (ora chiarita), fa parte di POSIX. (Tecnicamente, è un'estensione di sistema X / Open che POSIX ha incorporato. Vedi pubs.opengroup.org/onlinepubs/009695399/basedefs/stdio.h.html. )
Blrfl

Completamente d'accordo con tutto quanto sopra. Un buon esempio sono i sistemi Linux con pam_tmpdir: questo set TMPDIRe TMPdiverso per ogni utente, per robustezza e privacy. È anche utile essere in grado di impostare TMPDIRun singolo comando: se hai la solita directory temporanea in un filesystem RAM per la velocità, potresti doverlo fare per comandi che generano enormi file temporanei (come un gigante sort, ad esempio). Non ignorare gli standard / le convenzioni che i tuoi utenti si aspettano!
Toby Speight,

Controlla sicuramente l'ambiente per la posizione dei file temporanei e mai hard-code / tmp. Poiché un tmp condiviso presenta problemi di sicurezza, una mitigazione che ho visto spesso è quella di creare directory per utente / tmp senza autorizzazione di lettura / scrittura per nessun altro. Rimuove possibili condizioni di gara e attacchi symlink.
Zan Lynx,

9

La directory dei file temporanei dipende fortemente dal sistema operativo / dall'ambiente. Ad esempio una directory temp-web-server è separata dalla directory os-temp per motivi di sicurezza.

Sotto ms-windows ogni utente ha la sua temp-dir.

dovresti usare createTempFile () per questo se tale funzione è disponibile.


1
Basta essere consapevoli delle limitazioni nascoste del sistema operativo in Windows. Abbiamo scoperto che il numero massimo di file in una cartella era limitato a 65.565. Certo, ci sono molti file e, sicuramente, non dovresti mai immaginarne così tanti in giro. Ma sei sicuro che ogni app pulisca dopo se stessa in modo tempestivo e ben educato?
Mike Hofer,

Ah, ho visto il tuo commento troppo tardi. Ho appena scritto lo stesso sopra. A proposito, il limite è principalmente dovuto alla meccanica della funzione GetTimeFileName (), non a NTFS. Il limite di cartelle che hai menzionato si applica solo a FAT32 .
JensG,

9

Le risposte precedenti, sebbene corrette, non sono valide per la maggior parte dei cluster di computer.

I cluster di computer non seguono sempre le convenzioni standard per le macchine, di solito per buoni motivi, e non ha senso discuterne con gli amministratori di sistema.

La directory corrente si riferisce al file system centrale, a cui si accede attraverso la rete. Questo non è solo lento, ma carica anche il sistema per il resto degli utenti, quindi non dovresti usarlo a meno che tu non stia scrivendo molto e puoi recuperarlo se il lavoro si arresta in modo anomalo.

I nodi di calcolo hanno il proprio disco rigido, ovvero il file system più veloce disponibile e cosa dovresti usare. La documentazione del cluster dovrebbe dirti di cosa si tratta, in genere /scratch, /tmp/[jobid]o una variabile di ambiente non standard ( $SNIC_TMPin una di quelle che uso).

Quindi, ciò che raccomando è renderlo configurabile dall'utente. I valori predefiniti possono essere i primi a cui si ha accesso in scrittura a:

  • $TMPDIR
  • tmpfile
  • /tmp
  • .

Ma aspettati un basso tasso di successo con questo approccio e assicurati di emettere un grosso avviso grasso.

Modifica: aggiungerò un altro motivo per costringerlo a essere impostato dall'utente. Uno dei miei cluster è $TMPDIRimpostato su /scratch, che è scrivibile dall'utente e sul disco rigido locale. Ma la documentazione dice che tutto ciò che scrivi al di fuori di esso /scratch/[jobid]può essere eliminato in qualsiasi momento, anche durante la corsa. Quindi, se segui gli standard e ti fidi $TMPDIR, incontrerai crash casuali, molto difficili da eseguire il debug. Quindi, puoi accettare $TMPDIR, ma non fidarti.

Alcuni altri cluster hanno questa variabile correttamente configurata, quindi è possibile aggiungere un'opzione per fidarsi esplicitamente $TMPDIR, altrimenti emettere un grosso, grosso avviso.


1
Quali sono esattamente le risposte precedenti?
Tulains Córdova,

2
Quindi quello che stai dicendo qui è che, poiché alcuni cluster che non fanno il passo banale di aderire a uno standard ben consolidato per dire ai programmi dove scrivere i loro file temporanei, è necessaria un'ulteriore personalizzazione specifica del cluster per programma. Tè abbastanza debole se me lo chiedi.
Blrfl

@Blrfl puoi agitare gli standard quanto vuoi e scrivere un codice che si adatta perfettamente a loro e si blocca sempre; puoi provare a combattere con gli amministratori di sistema di ogni cluster che usi; oppure puoi accettare la tua fede e renderla configurabile. Inoltre, in HPC di solito è necessario adattare il codice alle specifiche del cluster (RAM disponibile, velocità relativa dei filesystem, implementazione MPI, disponibilità generale delle risorse ...), non esiste "una dimensione adatta a tutti".
Davidmh

@Davidmh: capito, ma non il punto. Lo standard lo rende configurabile in modo non sorprendente. Se porto il codice conforme a un cluster in cui lo standard non viene seguito, devo impostarlo esattamente in un punto, come nel punto di ingresso. Questa è una cosa in meno nel resto del codice da controllare, modificare e rischiare di sbagliare.
Blrfl

1

Per molte applicazioni, dovresti considerare di inserire file temporanei in $XDG_RUNTIME_DIRo $XDG_CACHE_HOME(le altre directory XDG sono per file non temporanei). Per istruzioni su come calcolarli se non vengono passati esplicitamente nell'ambiente, vedere le specifiche basate su XDG o trovare una libreria che implementa già quella parte.

Si noti, tuttavia, che $XDG_RUNTIME_DIRè una nuova aggiunta e non esiste un fallback standard per i sistemi più vecchi a causa di problemi di sicurezza.

Se nessuno di questi è adatto, allora /tmpè il posto giusto. Non dovresti mai supporre che la directory corrente sia scrivibile.


-2

Questo è più simile a un'alternativa, ma potresti scollegare il file () in modo non corretto dopo fopen (). Dipende dal modello di utilizzo del coraggio.

Scollegare i file, se possibile, aiuta in diversi modi:

  • il file non viene visualizzato - l'utente non lo vede.
  • il file non viene visualizzato da altri processi - non è possibile che altri processi modifichino il file per errore.
  • facile pulizia in caso di arresto anomalo del programma.

I file devono essere creati in / tmp. Se l'utente non ha i diritti per creare il file lì, significa che il sistema non è configurato correttamente.

I file non possono essere creati nella home directory degli utenti. Molti utenti, come "nessuno", "www-data" e molti altri, non hanno il diritto di scrivere nelle loro home directory, o sono persino chroot () - ed. Si noti che anche in ambiente chroot / tmp esiste ancora.


Anche se questa potrebbe essere una buona idea in generale, non aiuta gli utenti a cui mancano le autorizzazioni di scrittura sulla directory in cui creare il file.
5gon12eder

4
Inoltre non risponde alla domanda, che è dove mettere i file temporanei.
Blrfl,

Credo che la mia risposta sia in qualche modo importante. Ho fatto le modifiche, probabilmente è più chiaro in questo modo.
Nick,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.