2008-09-16 15 views
109

Une fois, j'ai lu qu'une façon d'obtenir un nom de fichier unique dans un shell pour les fichiers temporaires était d'utiliser un signe dollar double ($$). Cela produit un nombre qui varie de temps en temps ... mais si vous l'appelez à plusieurs reprises, il renvoie le même nombre. (La solution consiste simplement à utiliser l'heure.)

Je suis curieux de savoir ce qu'est réellement $$ et pourquoi il serait suggéré comme moyen de générer des noms de fichiers uniques.

Répondre

69

Dans Bash $$ est l'ID de processus, comme indiqué dans les commentaires, il est dangereux d'utiliser comme nom de fichier temporaire pour diverses raisons.

Pour les noms de fichiers temporaires, utilisez la commande mktemp.

+33

Pour les personnes qui cherchent juste à la réponse haut, $$ est pas bien, même pour un seul fichier si l'écriture dans un répertoire public-inscriptibles (par exemple,/tmp). Il est facile de mettre en litière/tmp avec des liens symboliques qui amèneront votre script à écrire quelque chose d'indésirable. mktemp est beaucoup mieux. –

+4

Ouais, en utilisant $$ va provoquer un trou de sécurité méchant. Ne fais pas ça. – emk

+2

quelqu'un avec assez de rep devrait éditer la réponse ... – dwestbrook

14

$$ est l'ID du processus en cours.

2

$$ est le pid du processus shell actuel. Ce n'est pas un bon moyen de générer des noms de fichiers uniques.

1

C'est l'ID de processus du processus bash. Aucun processus concurrent n'aura jamais le même PID.

6

Chaque processus dans un système d'exploitation de type UNIX possède un identificateur (temporaire) unique, le PID. Aucun processus en cours d'exécution en même temps ne peut avoir le même PID et $$ fait référence au PID de l'instance bash exécutant le script.

Ceci est beaucoup pas un identifiant unique en ce sens qu'il ne sera jamais réutilisé (en effet, les PID sont constamment réutilisés). Ce que cela vous donne est un nombre tel que, si une autre personne exécute votre script, ils auront un identifiant différent alors que le vôtre est toujours en cours d'exécution. Une fois que vous êtes mort, le PID peut être recyclé et quelqu'un d'autre peut exécuter votre script, obtenir le même PID, et ainsi obtenir le même nom de fichier. En tant que tel, il est vraiment sain de dire que "$$ donne un nom de fichier tel que si quelqu'un d'autre exécute le même script alors que mon instance est toujours en cours d'exécution, il aura un nom différent".

1

$$ est l'ID de processus du shell dans lequel votre script s'exécute. Pour plus de détails, voir la page man pour sh ou bash. Les pages man peuvent être trouvées soit en utilisant une ligne de commande "man sh", ou en cherchant sur le web pour "shell manpage"

4

$$ est votre PID. Il ne génère pas vraiment un nom de fichier unique, sauf si vous faites attention et que personne d'autre ne le fait exactement de la même manière.

En général, vous allez pouvoir créer quelque chose comme/tmp/myprogramname $$

Il sont tellement de façons de briser, et si vous écrivez à des endroits autres gens peuvent écrire ce n'est pas trop difficile sur de nombreux OS pour prédire quel PID vous allez avoir et vissez-vous - imaginez que vous êtes en train d'utiliser root et que je crée/tmp/yourprogname13395 en tant que lien symbolique pointant vers/etc/passwd - et vous y écrivez.

C'est une mauvaise chose à faire dans un script shell. Si vous allez utiliser un fichier temporaire pour quelque chose, vous devriez utiliser un meilleur langage qui vous permettra au moins d'ajouter le drapeau "exclusif" pour ouvrir (créer) le fichier. Ensuite, vous pouvez être sûr que vous n'essayez pas d'autre chose.

1

$$ est le pid (identifiant de processus) de l'interpréteur shell exécutant votre script. C'est différent pour chaque processus qui s'exécute sur un système pour le moment, mais avec le temps, le pid s'enroule, et après la sortie, il y aura un autre processus avec le même pid finalement.Tant que vous courez, le pid est unique pour vous. De la définition ci-dessus, il devrait être évident que, peu importe le nombre de fois que vous utilisez $$ dans un script, il retournera le même nombre.

Vous pouvez utiliser, par ex. /tmp/myscript.scratch.$$ comme fichier temporaire pour les choses qui n'ont pas besoin d'être extrêmement fiables ou sécurisées. Il est une bonne pratique de supprimer ces fichiers temporaires à la fin de votre script, en utilisant, par exemple, commande trap:

trap "echo 'Cleanup in progress'; rm -r $TMP_DIR" EXIT 
91

$$ est l'ID de processus (PID) en bash. L'utilisation de $$ est une mauvaise idée, car elle créera généralement une condition de concurrence et permettra à votre attaquant de corrompre votre shell-script. Voir, par exemple, tous les these people qui ont créé des fichiers temporaires non sécurisés et ont dû émettre des avis de sécurité. En revanche, utilisez mktemp. Le Linux man page for mktemp est excellent. Voici quelques exemples de code de celui-ci:

tempfoo=`basename $0` 
TMPFILE=`mktemp -t ${tempfoo}` || exit 1 
echo "program output" >> $TMPFILE 
+3

Merci. L'option 'mktemp'' -t' est maintenant obsolète (je pense à cause de problèmes avec le caractère '-'). ** Utilisez 'mktemp $ {tempfoo} .XXXXXX' ces jours-ci **. Je prends la liberté de mettre à jour votre message. – Sebastian

+0

Veuillez également noter que le [backtick était obsolète] (http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xcu_chap02.html#tag_23_02_06_03), utilisez plutôt 'TMPFILE = $ (mktemp)' à la place. –

1

Permettez-moi la réponse de deuxième EMK - ne pas utiliser $$ par lui-même comme quelque chose « unique ». Pour les fichiers, utilisez mktemp. Pour les autres ID dans le même script bash, utilisez "$$$ (date +% s% N)" pour obtenir une bonne chance d'unicité.

-k 
0

Vous pouvez également saisir le nom d'utilisateur via la connexion de cette commande. Par exemple.

echo $(</proc/$$/login id). After that, you need to use getent command.