Domanda

sto creando i file temporanei da uno script bash. Sto eliminarli al termine del trattamento, ma dal momento che lo script è in esecuzione per un periodo piuttosto lungo, se uccido o semplicemente CTRL-C durante la corsa, i file temporanei non vengono eliminate.
C'è un modo per catturare quegli eventi e la bonifica dei file prima dell'esecuzione finisce?

Inoltre, c'è una sorta di best practice per la denominazione e la posizione di quei file temporanei?
Non sono attualmente sicuro tra l'utilizzo di:

TMP1=`mktemp -p /tmp`
TMP2=`mktemp -p /tmp`
...

e

TMP1=/tmp/`basename $0`1.$$
TMP2=/tmp/`basename $0`2.$$
...

O forse c'è qualche soluzioni migliori?

È stato utile?

Soluzione

È possibile impostare un " trappola " per eseguire il uscire o su un controllo-c per ripulire.

trap "{ rm -f $LOCKFILE; }" EXIT

In alternativa, uno dei miei preferiti unix-ismi è quello di aprire un file, e quindi eliminarlo mentre hai ancora aperto. Il file rimane sul file system e si può leggere e scrivere, ma non appena il vostro programma esce, il file va via. Non sai come si farebbe che in bash, però.

A proposito: Un argomento darò a favore di mktemp invece di utilizzare la vostra soluzione: se l'utente anticipa il programma sta andando a creare enormi file temporanei, si potrebbe voler impostare TMPDIR da qualche parte più grande, come / var / tmp . mktemp riconosce che, la soluzione arrotolato a mano (seconda opzione) non lo fa. Io uso spesso TMPDIR=/var/tmp gvim -d foo bar, per esempio.

Altri suggerimenti

Io di solito creare una directory in cui collocare tutti i miei file temporanei, e poi subito dopo, creare un gestore EXIT per ripulire questa directory quando lo script esce.

MYTMPDIR=$(mktemp -d)
trap "rm -rf $MYTMPDIR" EXIT

Se si mettono tutti i file temporanei sotto $MYTMPDIR, allora saranno tutti eliminati quando lo script esce in più circostanze. Uccidere un processo con SIGKILL (kill -9) uccide il processo subito, però, in modo che il gestore EXIT non verrà eseguito in quel caso.

Si desidera utilizzare il comando trappola per gestire l'uscita dello script o segnali come CTRL-C. Vedere Wiki di Greg per i dettagli.

Per i vostri file temporanei, utilizzando basename $0 è una buona idea, oltre a fornire un modello che fornisce la stanza per i file temporanei sufficienti:

tempfile() {
    tempprefix=$(basename "$0")
    mktemp /tmp/${tempprefix}.XXXXXX
}

TMP1=$(tempfile)
TMP2=$(tempfile)

trap 'rm -f $TMP1 $TMP2' EXIT

Basta tenere a mente che scelto risposta è bashism, il che significa che la soluzione come

trap "{ rm -f $LOCKFILE }" EXIT

avrebbe funzionato solo in bash (che non prenderà Ctrl + c se shell è dash o sh classico), ma se volete la compatibilità allora avete ancora bisogno di elencare tutti i segnali che si vogliono intrappolare.

Anche tenere a mente che quando script esce la trappola per segnale "0" (EXIT alias) viene sempre effettuata con conseguente doppia esecuzione di comando trap.

Che la ragione non impilare tutti i segnali in una linea se c'è segnale EXIT.

Per capire meglio guardare seguente script che funzionerà su sistemi diversi, senza modifiche:

#!/bin/sh

on_exit() {
  echo 'Cleaning up...(remove tmp files, etc)'
}

on_preExit() {
  echo
  echo 'Exiting...' # Runs just before actual exit,
                    # shell will execute EXIT(0) after finishing this function
                    # that we hook also in on_exit function
  exit 2
}


trap on_exit EXIT                           # EXIT = 0
trap on_preExit HUP INT QUIT TERM STOP PWR  # 1 2 3 15 30


sleep 3 # some actual code...

exit 

Questa soluzione vi darà un maggiore controllo in quanto è possibile eseguire alcune delle vostro codice al verificarsi di segnale effettivo poco prima uscita (funzione preExit) finale e, se necessario, è possibile eseguire del codice a segnale di rimborso effettivamente (stadio finale di uscita)

L'alternativa di usare un nome di file prevedibile con $$ è un grosso problema di sicurezza e non si dovrebbe mai, mai, mai pensare di utilizzarlo. Anche se è solo un semplice script personali sul proprio PC singolo utente. Si tratta di una pessima abitudine non si deve ottenere. BugTraq è pieno di "di file temporaneo insicure" incidenti. Vedere qui , qui e qui per maggiori informazioni sul l'aspetto della sicurezza dei file temporanei.

Mi è stato inizialmente pensando di citare le assegnazioni tmp1 e tmp2 insicuri, ma ripensandoci che probabilmente non essere una buona idea .

Io preferisco usare tempfile che crea un file in / tmp in modo sicuro e tu non devi preoccuparti di sua denominazione:

tmp=$(tempfile -s "your_sufix")
trap "rm -f '$tmp'" exit

Non c'è bisogno di preoccuparsi di rimuovere i file TMP creati con mktemp. Essi verranno eliminati comunque in seguito.

Utilizzare mktemp se è possibile in quanto genera file più unico poi '$$' prefisso. E sembra che più modo cross platform per creare file temporanei poi esplicitamente metterli in / tmp.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top