Trovare la directory tmp corretta su più piattaforme


46

Ho uno script che deve creare file temporanei per il suo lavoro e ripulire dopo se stesso. La mia domanda riguarda la ricerca della giusta directory di base per i file temporanei.

Lo script deve funzionare su più piattaforme: Git Bash (Windows), Solaris, Linux, OSX. Su ciascuna piattaforma, la directory temporanea preferita è espressa in modo diverso:

  • Windows: %TMP%(e possibilmente %TEMP%)
  • OSX: $TMPDIR
  • Linux, UNIX: dovrebbe essere $TMPDIRma sembra non essere impostato su più sistemi che ho provato

Quindi nella mia sceneggiatura ho aggiunto questo bollettino:

if test -d "$TMPDIR"; then
    :
elif test -d "$TMP"; then
    TMPDIR=$TMP
elif test -d /var/tmp; then
    TMPDIR=/var/tmp
else
    TMPDIR=/tmp
fi

Sembra troppo noioso. C'è un modo migliore?


6
Basta usare ${TMPDIR-/tmp}su Unix-like. TMPDIRc'è (dal sistema o dall'amministratore o dall'utente) per dirti quando non utilizzare /tmpper i file temporanei.
Stéphane Chazelas,

Risposte:


72

È possibile utilizzare un modo leggermente più portatile per gestire i file temporanei mktemp. Creerà file temporanei e restituirà i loro percorsi per te. Per esempio:

$ mktemp
/tmp/tmp.zVNygt4o7P
$ ls /tmp/tmp.zVNygt4o7P
/tmp/tmp.zVNygt4o7P

Potresti usarlo in uno script abbastanza facilmente:

tmpfile=$(mktemp)
echo "Some temp. data..." > $tmpfile
rm $tmpfile

Leggendo la pagina man, dovresti essere in grado di impostare le opzioni in base alle tue esigenze. Per esempio:

  • -d crea una directory anziché un file.
  • -u genera un nome, ma non crea nulla.

Usando -upotresti recuperare abbastanza facilmente la directory temporanea con ...

$ tmpdir=$(dirname $(mktemp -u))

Maggiori informazioni mktempsono disponibili qui .

Modifica per quanto riguarda Mac OS X: non ho mai usato un sistema Mac OSX, ma secondo un commento di Tyilo di seguito, sembra che Mac OSX mktemprichieda di fornire un modello (che è un argomento opzionale su Linux). citando:

Il modello può essere qualsiasi nome di file con un numero di "X" ad esso aggiunto, ad esempio /tmp/temp.XXXX. Le "X" finali vengono sostituite con l'attuale numero di processo e / o una combinazione di lettere univoca. Il numero di nomi file univoci che mktemp può restituire dipende dal numero di "X" fornite; sei "X" comporteranno la selezione di 1 di 56800235584 (62 ** 6) nomi di file possibili da mktemp.

La pagina man dice anche che questa implementazione è ispirata alla pagina man di OpenBSD per mktemp. Una divergenza simile potrebbe quindi essere osservata anche dagli utenti OpenBSD e FreeBSD (vedere la sezione Cronologia ).

Ora, come probabilmente avrai notato, questo richiede di specificare un percorso file completo, inclusa la directory temporanea che stai cercando nella tua domanda. Questo piccolo problema può essere gestito usando l' -tinterruttore. Mentre questa opzione sembra richiedere un argomento ( prefix), sembrerebbe che mktempsi basi su $TMPDIRquando necessario.

Tutto sommato, dovresti essere in grado di ottenere lo stesso risultato sopra usando ...

$ tmpdir=$(dirname $(mktemp tmp.XXXXXXXXXX -ut))

Qualsiasi feedback da parte degli utenti di Mac OS X sarebbe molto apprezzato, poiché non sono in grado di testare questa soluzione da solo.


Il PO ha affrontato questo problema in un commento ora cancellato; Temo di non poter fornire una risposta per i sistemi che richiedono gitbashun'interfaccia shell, quindi il mio "leggermente". In realtà non sarei in grado di dire dove sono archiviati i file temporanei su un sistema Windows ...
John WH Smith il

1
idem quello. Alcuni pazzi c:\User\Name\..............\stuff. E probabilmente ce ne sono 100. Tuttavia, alcune distro di Linux si stanno avvicinando allo stesso livello di follia /var. Ero solo curioso. Mi è sembrato uno strano modo di dirlo: tutto nella mia esperienza la frustrazione è molto portatile e la convenienza meno. Ottima risposta comunque.
Mikeserv,

1
Circa un anno fa ho scritto uno script Bash per manipolare i file di punti di ripristino di Windows che funzionano da Win2K a WinXP (le versioni successive gestiscono le cose in modo diverso). Il mio script utilizza WINDOWS/Tempo Windows/Tempcome directory predefinita per i suoi file temporanei; quella directory esiste anche su macchine Windows 7. Ma il mio script consente all'utente di fornire una directory temporanea alternativa sulla riga di comando.
PM 2Ring

Questo non funzionerebbe su OS X, poiché è necessario fornire un modello a mktemp.
Tyilo,

1
Dal momento che El Capitan, mktempfunziona: semplice mktemprestituisce un file e mktemp -drestituisce una directory; nessun modello richiesto. Il manuale non è aggiornato però.
Franklin Yu,

9

Se stai cercando la stessa cosa in meno righe ...

for TMPDIR in "$TMPDIR" "$TMP" /var/tmp /tmp
do
    test -d "$TMPDIR" && break
done

Potresti scrivere questo in uno.


Probabilmente dovresti anche testare se è scrivibile.
frostschutz,

@janos: E se tutto il resto fallisce, chiedi all'utente di fornire un percorso per i file temporanei o consenti loro di specificarne uno sulla riga di comando.
PM 2Ring

6

Potresti fare:

: "${TMPDIR:=${TMP:-$(CDPATH=/var:/; cd -P tmp)}}"
cd -- "${TMPDIR:?NO TEMP DIRECTORY FOUND!}" || exit

La shell dovrebbe trovare una directory eseguibile in una delle 4 alternative o uscire con un errore significativo. Tuttavia, POSIX definisce la $TMPDIRvariabile (per i sistemi XCU) :

TMPDIR Questa variabile deve rappresentare un percorso di una directory resa disponibile per i programmi che necessitano di un posto per creare file temporanei.

Richiede anche il /tmppercorso.


1
Questa è l'unica risposta giusta qui IMO. Non so cosa sta facendo sedere in fondo senza voti ...
Graeme,

2
@Graeme: forse perché è assolutamente illeggibile?
ssc,

Ho votato ma poi l'ho ritirato-- sì, questa risposta è un disastro, sembra essere su una traccia utile, ma non è affatto chiaro cosa stia cercando di fare lo snippit di codice - la prima riga è un commento e la seconda uno è un errore (in bash, comunque). Potrebbe usare del lavoro.
Don Hatch,

Oh, capisco, la prima versione della risposta è stata più chiara (ancora un errore sulla seconda riga se in realtà si tenta di eseguirla) ... e poi una serie di modifiche ha completamente eliminato l'esempio di codice, quindi ora è una sciocchezza. Potrebbe usare un altro passaggio o due :-)
Don Hatch,
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.