web-dev-qa-db-fra.com

Trouver le bon répertoire tmp sur plusieurs plateformes

J'ai un script qui doit créer des fichiers temporaires pour son travail et nettoyer après lui-même. Ma question est de trouver le bon répertoire de base pour les fichiers temporaires.

Le script doit fonctionner sur plusieurs plateformes: Git Bash (Windows), Solaris, Linux, OSX. Sur chaque plateforme, le répertoire temporaire préféré s'exprime différemment:

  • Les fenêtres: %TMP% (et éventuellement %TEMP%)
  • OSX: $TMPDIR
  • Linux, UNIX: censé être $TMPDIR mais semble ne pas être réglé sur plusieurs systèmes, j'ai essayé

Donc, dans mon script, j'ai ajouté ce passe-partout:

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

Cela semble trop fastidieux. Y a-t-il une meilleure façon?

48
janos

Une façon légèrement plus portable de gérer les fichiers temporaires consiste à utiliser mktemp. Il va créer des fichiers temporaires et retourner leurs chemins pour vous. Par exemple:

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

Vous pouvez l'utiliser assez facilement dans un script:

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

En lisant la page de manuel, vous devriez pouvoir définir des options selon vos besoins. Par exemple:

  • -d crée un répertoire au lieu d'un fichier.
  • -u génère un nom, mais ne crée rien.

En utilisant -u vous pouvez récupérer le répertoire temporaire assez facilement avec ...

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

Plus d'informations sur mktemp sont disponibles ici .

Modifier concernant Mac OS X: Je n'ai jamais utilisé de système Mac OSX, mais selon un commentaire de Tyilo ci-dessous, il semble que mktemp de Mac OSX vous oblige pour fournir un modèle (qui est un argument facultatif sous Linux). Citant:

Le modèle peut être n'importe quel nom de fichier auquel est ajouté un certain nombre de "X", par exemple /tmp/temp.XXXX. Les "X" de fin sont remplacés par le numéro de processus actuel et/ou une combinaison de lettres unique. Le nombre de noms de fichiers uniques que mktemp peut renvoyer dépend du nombre de "X" fournis; six "X" se traduiront par mktemp sélectionnant 1 des noms de fichiers possibles 56800235584 (62 ** 6).

La page de manuel indique également que cette implémentation est inspirée de la page de manuel d'OpenBSD pour mktemp. Une divergence similaire pourrait donc être observée par les utilisateurs d'OpenBSD et de FreeBSD également (voir la section Historique )!

Maintenant, comme vous l'avez probablement remarqué, cela vous oblige à spécifier un chemin de fichier complet, y compris le répertoire temporaire que vous recherchez dans votre question. Ce petit problème peut être traité en utilisant le -t commutateur. Bien que cette option semble nécessiter un argument (prefix), il semblerait que mktemp repose sur $TMPDIR quand c'est nécessaire.

Dans l'ensemble, vous devriez pouvoir obtenir le même résultat que ci-dessus en utilisant ...

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

Tout commentaire des utilisateurs de Mac OS X serait grandement apprécié, car je ne peux pas tester cette solution moi-même.

76
John WH Smith

Si vous cherchez la même chose en moins de lignes ...

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

Vous pourriez écrire ceci en un seul.

10
frostschutz

Vous pourriez faire:

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

Le shell doit soit trouver un répertoire exécutable dans l'une des 4 alternatives, soit se terminer par une erreur significative. Pourtant, POSIX définit le $TMPDIR variable (pour les systèmes XCU):

TMPDIR Cette variable doit représenter le chemin d'un répertoire mis à disposition pour les programmes qui ont besoin d'un emplacement pour créer des fichiers temporaires.

Il requiert également le /tmp chemin.

6
mikeserv