140 votes

Suppression des fichiers temporaires créés lors d'une sortie inattendue de bash

Je suis la création de fichiers temporaires à partir d'un script bash. Je suis de les supprimer à la fin du traitement, mais depuis que le script est en cours d'exécution pendant un temps assez long, si je le tuer ou simplement CTRL-C au cours de l'exécution, les fichiers temporaires ne sont pas supprimés.
Est il possible que je peux attraper ces événements et de nettoyer les fichiers avant la fin de l'exécution?

Aussi, est-il une sorte de bonne pratique pour la désignation et l'emplacement de ces fichiers temporaires?
Actuellement, je suis pas sûr entre l'utilisation de:

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

et

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

Ou peut-être est-il de meilleures solutions?

180voto

Chris AtLee Points 3656

Je crée généralement un répertoire dans lequel placer tous mes fichiers temporaires, puis immédiatement après, je crée un gestionnaire EXIT pour nettoyer ce répertoire lorsque le script se ferme.

 MYTMPDIR=`mktemp -d`
trap "rm -rf $MYTMPDIR" EXIT
 

Si vous placez tous vos fichiers temporaires sous $MYTMPDIR , ils seront tous supprimés à la fin de votre script, dans la plupart des cas. Tuer un processus avec SIGKILL (kill -9) tue tout de suite le processus, de sorte que votre gestionnaire EXIT ne s'exécutera pas dans ce cas.

119voto

Paul Tomblin Points 83687

Vous pouvez définir un "piège" pour exécuter sur un control-c pour nettoyer.

Sinon, un de mes préférés unix ambition est d'ouvrir un fichier, puis de le supprimer alors que vous l'avez encore ouvert. Le fichier reste sur le système de fichiers et vous pouvez le lire et à l'écrire, mais dès que votre programme se termine, le fichier disparaît. Pas sûr comment vous pouvez le faire en bash, cependant.

BTW: Un argument que je vais donner en faveur de mktemp au lieu d'utiliser votre propre solution: si l'utilisateur prévoit de votre programme va créer d'énormes fichiers temporaires, il pourrait définir "TMPDIR" à quelque part de plus grande, comme /var/tmp. mktemp reconnaît que, votre roulés à la main de la solution (deuxième option) ne fonctionne pas. J'utilise fréquemment "TMPDIR=/var/tmp gvim -d foo bar", par exemple.

31voto

Brian Campbell Points 101107

Vous souhaitez utiliser la commande trap pour gérer la sortie du script ou des signaux tels que CTRL-C. Consultez le Guide de script avancé Bash pour plus de détails.

Pour vos fichiers temporaires, utiliser basename $0 est une bonne idée, en plus de fournir un modèle offrant suffisamment de place pour des fichiers temporaires:

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

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

trap 'rm -f $TMP1 $TMP2' EXIT
 

5voto

hlovdal Points 11039

L'alternative de l'utilisation prévisible de nom de fichier de $$ est un énorme trou de sécurité et vous ne devriez jamais, jamais, jamais penser à utiliser. Même si c'est juste un simple script personnel sur votre PC utilisateur. C'est une très mauvaise habitude, vous ne devriez pas obtenir. BugTraq est pleine de "l'insécurité temp fichier" incidents. Voir ici, ici et ici pour plus d'informations sur l'aspect sécurité des fichiers temporaires.

J'ai d'abord été pensée de citer l'insécurité TMP1 et TMP2 devoirs, mais sur la deuxième pensée qui ne serait probablement pas une bonne idée.

1voto

Ruslan Kabalin Points 1550

Je préfère utiliser tempfile qui crée un fichier dans / tmp de manière sécurisée et vous n'avez pas à vous soucier de son nom:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X