Que signifie $$ dans la coquille?

143

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

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

Minou
la source

Réponses:

102

Dans Bash se $$trouve l'ID de processus, comme indiqué dans les commentaires, il n'est pas sûr de l'utiliser comme nom de fichier temporaire pour diverses raisons.

Pour les noms de fichiers temporaires, utilisez la mktempcommande.

Joe Skora
la source
35
Pour les personnes qui ne regardent que la première réponse, $$ ne convient pas même pour un seul fichier si elles écrivent dans un répertoire accessible en écriture (par exemple, / tmp). Il est facile de jeter / tmp avec des liens symboliques qui entraîneront l'écriture de votre script quelque part indésirable. mktemp est bien meilleur.
Chris Jester-Young
4
Ouais, utiliser $$ causera une faille de sécurité désagréable. Ne fais pas ça.
emk
7
Ou la personne qui a posé la question doit définir la réponse la mieux notée ci-dessous comme réponse acceptée ...
jtimberman
6
J'ajoute "dollar dollar" pour le référencement.
Antoine
1
Si $$ sort juste le pid, comment peut-il être "non sûr"? Une faille de sécurité est créée en raison d'une mauvaise conception et non de l'utilisation du PID dans le nom de fichier tmp ... Si vous vous souciez tellement de l'intégrité de la sortie qui va à tmp, peut-être que vous ne devriez même pas le mettre là en premier lieu? $$ ne causera pas de trou de sécurité, le manque de prévoyance sera
niken
113

$$est l'ID de processus (PID) dans bash. L'utilisation $$est une mauvaise idée, car elle créera généralement une condition de concurrence et permettra à votre script shell d'être corrompu par un attaquant. Voyez, par exemple, toutes ces personnes qui ont créé des fichiers temporaires non sécurisés et ont dû émettre des avis de sécurité.

Utilisez plutôt mktemp. La page de manuel Linux pour mktemp est excellente. En voici un exemple de code:

tempfoo=`basename $0`
TMPFILE=`mktemp -t ${tempfoo}` || exit 1
echo "program output" >> $TMPFILE
emk
la source
3
Merci. L' mktempoption -test maintenant obsolète (je pense à cause de problèmes avec le char -). Utilisez mktemp ${tempfoo}.XXXXXXces jours-ci . Je prends la liberté de mettre à jour votre message.
Sebastian
1
Veuillez également noter que le backtick était obsolète , alors utilisez-le à la TMPFILE=$(mktemp)place.
Michael Kopp
20

$$ est l'identifiant du processus en cours.

Silex
la source
7

Chaque processus dans un système d'exploitation semblable à UNIX a un identifiant unique (temporairement), le PID. Aucun processus exécuté 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.

Ce n'est vraiment pas un identifiant unique dans le sens où il ne sera jamais réutilisé (en effet, les PID sont réutilisés constamment). Cela vous donne un nombre tel que, si une autre personne exécute votre script, elle obtiendra un identifiant différent pendant que le vôtre est toujours en cours d'exécution. Une fois que le vôtre meurt, 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 tout à fait raisonnable de dire "$$ 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 obtiendra un nom différent".

Adam Wright
la source
5

$$ est votre PID. Cela ne génère pas vraiment de nom de fichier unique, à moins que vous ne soyez prudent et que personne d'autre ne le fasse exactement de la même manière.

En général, vous créez quelque chose comme / tmp / myprogramname $$

Il y a tellement de façons de briser cela, et si vous écrivez à des endroits où d'autres personnes peuvent écrire, il n'est pas trop difficile sur de nombreux systèmes d'exploitation de prédire quel PID vous allez avoir et de visser - imaginez que vous exécutez en tant que root et 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 de ne pas frapper autre chose.

JBB
la source
3

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

leif
la source
3

$$ est le pid (identifiant de processus) de l'interpréteur shell exécutant votre script. C'est différent pour chaque processus en cours d'exécution sur un système pour le moment, mais avec le temps, le pid s'enroule, et après votre sortie, il y aura un autre processus avec le même pid, tant que vous exécutez, le pid vous est unique.

D'après la définition ci-dessus, il devrait être évident que peu importe le nombre de fois que vous utilisez $$ dans un script, il renverra le même nombre.

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

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

la source
2

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


la source
2

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

Shannon Nelson
la source
2

Permettez-moi de seconder la réponse d'emk - n'utilisez pas $$ 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 une chance raisonnablement bonne d'unicité.

 -k
Kevin Little
la source
0

En outre, vous pouvez saisir le nom d'utilisateur de connexion via cette commande. Par exemple.

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