https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s3-proc-self.html dit
Le
/proc/self/
Le répertoire est un lien vers le processus en cours d'exécution.
Il y a toujours plusieurs processus qui s'exécutent simultanément, alors quel processus est "le processus en cours d'exécution"?
"Le processus en cours d'exécution" a-t-il quelque chose à voir avec le processus en cours d'exécution sur le processeur, compte tenu du changement de contexte?
"Le processus en cours d'exécution" n'a-t-il rien à voir avec les processus de premier plan et d'arrière-plan?
Cela n'a rien à voir avec les processus de premier plan et d'arrière-plan; cela ne concerne que le processus en cours d'exécution. Lorsque le noyau doit répondre à la question "Qu'est-ce que /proc/self
pointer vers? ", il suffit sélectionne le pid actuellement planifié , ie le processus en cours d'exécution (sur le courant CPU logique). L'effet est que /proc/self
pointe toujours sur le pid du programme demandé; si tu cours
ls -l /proc/self
vous verrez le pid de ls
, si vous écrivez du code qui utilise /proc/self
ce code verra son propre pid, etc.
Celui qui accède au lien symbolique (appelle readlink () dessus ou open () sur un chemin qui le traverse). Il fonctionnerait sur le CPU à l'époque, mais ce n'est pas pertinent. Un système multiprocesseur peut avoir plusieurs processus simultanément sur le CPU.
Les processus de premier plan et d'arrière-plan sont principalement une construction Shell, et il n'y a pas non plus de processus unique de premier plan, car toutes les sessions Shell du système en auront un.
La formulation aurait pu être meilleure, mais là encore, toute formulation que vous essayez de composer pour exprimer l'idée d'auto-référence sera source de confusion. Le nom du répertoire est plus descriptif à mon avis.
Fondamentalement, /proc/self/
représente le processus en cours de lecture /proc/self/
. Donc, si vous essayez d'ouvrir /proc/self/
d'un programme C alors il représente ce programme. Si vous essayez de le faire à partir du Shell, alors c'est le Shell, etc.
Mais que se passe-t-il si vous avez un processeur quad core capable d'exécuter 4 processus simultanément, pour de vrai, pas multitâche?
Ensuite, chaque processus verra un /proc/self/
pour de vrai sans pouvoir se voir /proc/self/
.
Comment ça marche?
Bien, /proc/self/
n'est pas vraiment un dossier. Il s'agit d'un pilote de périphérique qui s'expose en tant que dossier si vous essayez d'y accéder. En effet, il implémente l'API nécessaire pour les dossiers. Le /proc/self/
le répertoire n'est pas la seule chose à faire cela. Considérez les dossiers partagés montés à partir de serveurs distants ou le montage de clés USB ou dropbox. Ils fonctionnent tous en implémentant le même ensemble d'API qui les font se comporter comme des dossiers.
Lorsqu'un processus tente d'accéder à /proc/self/
le pilote de périphérique générera son contenu dynamiquement en lisant les données de ce processus. Ainsi, les fichiers dans /proc/self/
n'existe pas vraiment. C'est un peu comme un miroir qui réfléchit sur le processus qui essaie de le regarder.
Est-ce vraiment un pilote de périphérique? On dirait que vous simplifiez trop les choses!
Oui, vraiment. Si vous voulez être pédant, c'est un module du noyau. Mais si vous consultez les publications usenet sur les différents canaux de développeurs Linux, la plupart des développeurs de noyau utilisent de manière interchangeable "pilote de périphérique" et "module de noyau". J'avais l'habitude d'écrire des pilotes de périphériques, des modules de noyau ... pour Linux. Si vous souhaitez écrire votre propre interface en /proc/
, disons par exemple que vous voulez un /proc/unix.stackexchange/
système de fichiers qui renvoie des articles de ce site Web, vous pouvez lire comment le faire dans le vénérable livre "Linux Device Drivers" publié par O'Reilly. Il est même disponible en ligne sur papier.
C'est le processus qui accède à /proc/self
ou les fichiers/dossiers qui s'y trouvent.
Essayez cat /proc/self/cmdline
. Vous obtiendrez, surprise surprise, cat /proc/self/cmdline
, (en fait, au lieu d'un espace, il y aura un caractère nul entre le t
et le /
) car ce sera le processus cat accédant à ce pseudofichier.
Lorsque vous effectuez un ls -l /proc/self
, vous verrez le pid du processus ls lui-même. Ou que diriez-vous ls -l /proc/self/exe
; il pointera vers l'exécutable ls.
Ou essayez ceci, pour un changement:
$ cp /proc/self/cmdline /tmp/cmd
$ hexdump -C /tmp/cmd
00000000 63 70 00 2f 70 72 6f 63 2f 73 65 6c 66 2f 63 6d |cp./proc/self/cm|
00000010 64 6c 69 6e 65 00 2f 74 6d 70 2f 63 6d 64 00 |dline./tmp/cmd.|
0000001f
ou même
$ hexdump -C /proc/self/cmdline
00000000 68 65 78 64 75 6d 70 00 2d 43 00 2f 70 72 6f 63 |hexdump.-C./proc|
00000010 2f 73 65 6c 66 2f 63 6d 64 6c 69 6e 65 00 |/self/cmdline.|
0000001e
Comme je l'ai dit, c'est le processus qui accède à /proc/self
ou les fichiers/dossiers qui s'y trouvent.
/ proc/self est du sucre syntaxique. C'est un raccourci vers la contaténation de/proc/et le résultat du syscall getpid () (accessible en bash comme la métavariable $$). Cela peut devenir déroutant, cependant, dans le cas des scripts Shell, car de nombreuses instructions invoquent d'autres processus, avec leurs propres PID ... PID qui font référence, le plus souvent, à des processus morts. Considérer:
root@vps01:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 Jan 1 01:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jan 1 01:51 3 -> /proc/26562/fd
root@vps01:~# echo $$
593
'/ bin/ls' évaluera le chemin d'accès au répertoire, en le résolvant comme/proc/26563, puisque c'est le PID du processus - le processus/bin/ls nouvellement créé - qui lit le contenu du répertoire. Mais au moment où le prochain processus dans le pipeline, dans le cas des scripts Shell, ou au moment où l'invite revient, dans le cas d'un shell interactif, le chemin n'existe plus et les informations la sortie fait référence à un processus inexistant.
Cependant, cela ne s'applique qu'aux commandes externes (celles qui sont de véritables fichiers programme exécutables, par opposition à être intégrées dans le shell lui-même). Ainsi, vous obtiendrez des résultats différents si, par exemple, vous utilisez le remplacement de nom de fichier pour obtenir une liste du contenu du répertoire, plutôt que de transmettre le nom du chemin au processus externe/bin/ls:
root@vps01:~# ls /proc/self/fd
0 1 2 3
root@vps01:~/specs# echo /proc/self/fd/*
/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
Dans la première ligne, le shell a généré un nouveau processus, '/ bin/ls', via le syscall exec (), en passant "/ proc/self/fd" comme argv [1]. '/ bin/ls', à son tour, a ouvert le répertoire/proc/self/fd et a lu, puis imprimé, son contenu en itérant sur eux.
Cependant, la deuxième ligne utilise glob () en arrière-plan pour développer la liste des noms de fichiers; ceux-ci sont passés comme un tableau de chaînes à faire écho. (Habituellement implémenté comme une commande interne, mais il y a souvent aussi un binaire/bin/echo ... mais cette partie n'est en fait pas pertinente, car echo ne traite que des chaînes qu'il ne nourrit jamais pour aucun appel système lié aux noms de chemin.)
Maintenant, considérons le cas suivant:
root@vps01:~# cd /proc/self/fd
root@vps01:~# ls
0 1 2 255
Ici, le Shell, le processus parent de/bin/ls, a fait d'un sous-répertoire de/proc/self son répertoire courant. Ainsi, les chemins d'accès relatifs sont évalués de son point de vue. Ma meilleure supposition est que cela est lié à la sémantique des fichiers POSIX où vous pouvez créer plusieurs liens durs vers un fichier, y compris tout descripteur de fichier ouvert. Donc, cette fois,/bin/ls se comporte de la même manière que echo/proc/$$/fd/*.