Linux /proc/<pid>/environne met pas à jour (si j'ai bien compris, le fichier contient l'environnement initial du processus).
Comment lire l' environnement actuel d' un processus ?
Linux /proc/<pid>/environne met pas à jour (si j'ai bien compris, le fichier contient l'environnement initial du processus).
Comment lire l' environnement actuel d' un processus ?
Réponses:
/proc/$pid/environmet à jour si le processus change son propre environnement. Mais de nombreux programmes ne prennent pas la peine de changer leur propre environnement, car il est un peu inutile: l'environnement d'un programme ne sont pas visibles par les voies normales, que par /procet ps, et même pas toutes les variantes unix a ce genre de fonction, afin que les applications ne reposent pas dessus.
En ce qui concerne le noyau, l'environnement n'apparaît que comme l'argument de l' execveappel système qui lance le programme. Linux expose une zone en mémoire /proc, et certains programmes la mettent à jour alors que d’autres ne le font pas. En particulier, je ne pense pas qu’un shell mette à jour ce domaine. Comme la zone a une taille fixe, il serait impossible d’ajouter de nouvelles variables ou de modifier la longueur d’une valeur.
PATH=foodans un shell que celui-ci va être modifié *envp. Dans certains shells, seule la structure de données interne est mise à jour et le code d'exécution du programme externe est mis à jour *envp. Regardez assign_in_envdans variables.cla source de bash, par exemple.
forkalors libc effectue l' sys_forkappel à l'aide de l'environnement alloué par tas pour le processus enfant.
argvsont plus courants mais les deux existent).
Vous pouvez lire l' environnement initial d'un processus à partir de /proc/<pid>/environ.
Si un processus modifie son environnement, pour lire l'environnement, vous devez disposer de la table des symboles pour le processus et utiliser l' ptraceappel système (par exemple, à l'aide de gdb) pour lire l'environnement à partir de la char **__environvariable globale . Il n'y a pas d'autre moyen d'obtenir la valeur d'une variable à partir d'un processus Linux en cours d'exécution.
C'est la réponse. Maintenant pour quelques notes.
Ce qui précède suppose que le processus est conforme à POSIX, ce qui signifie qu'il gère son environnement à l'aide d'une variable globale char **__environspécifiée dans la spécification de référence .
L'environnement initial d'un processus est transmis au processus dans un tampon de longueur fixe sur la pile du processus. (Le mécanisme habituel est le cas linux//fs/exec.c:do_execve_common(...).) Étant donné que la taille de la mémoire tampon est calculée au maximum de la taille requise pour l'environnement initial, vous ne pouvez pas ajouter de nouvelles variables sans effacer les variables existantes ou détruire la pile. Ainsi, tout schéma raisonnable permettant des modifications dans l'environnement d'un processus utiliserait le tas, où de la mémoire de tailles arbitraires peut être allouée et libérée, ce qui est exactement ce que GNU libc( glibc) fait pour vous.
Si le processus utilise glibc, il est conforme à POSIX. Après __environavoir été déclaré dans glibc//posix/environ.cGlibc, il est initialisé __environavec un pointeur sur la mémoire mallocextraite du segment de mémoire du processus, puis copie l’environnement initial de la pile dans cette zone. Chaque fois que le processus utilise la setenvfonction, glibcne a reallocpour ajuster la taille de la surface qui __environpointe vers pour tenir compte de la nouvelle valeur ou variable. (Vous pouvez télécharger le code source de glibc avec git clone git://sourceware.org/git/glibc.git glibc). Pour bien comprendre le mécanisme, vous devrez également lire le code Hurd dans hurd//init/init.c:frob_kernel_process()(git clone git: //git.sv.gnu.org/hurd/hurd.git hurd).
Maintenant , si le nouveau processus forkn'ed, sans suite execécraser la pile, l'argument et l' environnement magique de la copie se fait dans linux//kernel/fork.c:do_fork(...), où les copy_processappels de routine dup_task_structqui attribue la pile du nouveau processus en appelant alloc_thread_info_node, qui appelle setup_thread_stack( linux//include/linux/sched.h) pour le nouveau processus à l' aide alloc_thread_info_node.
Enfin, la __environconvention POSIX est une convention d’ espace utilisateur . Il n’a aucun lien avec quoi que ce soit dans le noyau Linux. Vous pouvez écrire un programme en espace utilisateur sans utiliser glibcet sans le __environglobal, puis gérer les variables d'environnement comme bon vous semble. Personne ne vous arrêtera pour cela, mais vous devrez écrire vos propres fonctions de gestion de l’environnement ( setenv/ getenv) et vos propres wrappers sys_exec. Il est probable que personne ne sera en mesure de deviner où vous mettez les changements dans votre environnement.
/proc/[pid]/semblent avoir un encodage étrange (quelqu'un d'autre peut savoir quoi et pourquoi). Pour moi, il cat environsuffirait d’imprimer les variables d’environnement dans un format très difficile à lire. cat environ | stringsrésolu ceci pour moi.
Il est mis à jour au fur et à mesure que le processus acquiert / supprime ses variables d'environnement. Avez-vous une référence indiquant que le environfichier n'est pas mis à jour pour le processus dans son répertoire de processus sous / proc filesystem?
xargs --null --max-args=1 echo < /proc/self/environ
ou
xargs --null --max-args=1 echo < /proc/<pid>/environ
ou
ps e -p <pid>
Ce qui précède imprimera les variables d’environnement du processus au psformat de sortie. Un traitement de texte (analyse / filtrage) est nécessaire pour afficher les variables d’environnement sous forme de liste.
Solaris (non demandé, mais pour référence je posterai ici):
/usr/ucb/ps -wwwe <pid>
ou
pargs -e <pid>
EDIT: / proc / pid / environ n'est pas mis à jour! Je me suis trompé. Le processus de vérification est ci-dessous. Cependant, les enfants dont le processus est fork héritent de la variable d'environnement de processus et celle-ci est visible dans leur fichier / proc / self / environ respectif. (Utilisez des chaînes)
Avec dans le shell: xargs est ici un processus enfant et hérite donc de la variable d’environnement et se reflète également dans son /proc/self/environfichier.
[centos@centos t]$ printenv | grep MASK
[centos@centos t]$ export MASK=NIKHIL
[centos@centos t]$ printenv | grep MASK
MASK=NIKHIL
[centos@centos t]$ xargs --null --max-args=1 echo < /proc/self/environ | grep MASK
MASK=NIKHIL
[centos@centos t]$ unset MASK
[centos@centos t]$ printenv | grep MASK
[centos@centos t]$ xargs --null --max-args=1 echo < /proc/self/environ | grep MASK
[centos@centos t]$
Vérification à partir d'une autre session, où le terminal / session n'est pas le processus enfant du shell où la variable d'environnement est définie.
Vérification à partir d'un autre terminal / session sur le même hôte:
terminal1:: Notez que printenv est fork'd et est un processus enfant de bash et qu'il lit donc son propre fichier environ.
[centos@centos t]$ echo $$
2610
[centos@centos t]$ export SPIDEY=NIKHIL
[centos@centos t]$ printenv | grep SPIDEY
SPIDEY=NIKHIL
[centos@centos t]$
terminal2: sur le même hôte - ne le lancez pas dans le même shell que celui où la variable ci-dessus a été définie, lancez le terminal séparément.
[centos@centos ~]$ echo $$
4436
[centos@centos ~]$ xargs --null --max-args=1 echo < /proc/self/environ | grep -i spidey
[centos@centos ~]$ strings -f /proc/2610/environ | grep -i spidey
[centos@centos ~]$ xargs --null --max-args=1 echo < /proc/2610/environ | grep -i spidey
[centos@centos ~]$
export foo=bardans la session de one bash (pid xxxx), puis cat /proc/xxxx/environ | tr \\0 \\ndans la session de l'autre bash et je ne vois pas foo.
gdb au pid, mais toujours aucune référence. Le bloc de variables d'environnement en mémoire est réaffecté chaque fois qu'il y a un changement et qu'il n'est pas reflété dans le fichier d'environnement de son propre processus dans le système de fichiers proc, mais permet cependant d'être hérité par le processus enfant. Cela signifie que cela pourrait devenir plus facile de connaître les détails intrinsèques lorsque la fourchette se produit, comment le processus enfant obtient-il les variables d'environnement copiées telles quelles.
Ce qui suit n’est pas lié aux intentions réelles de l’auteur, mais si vous voulez vraiment "LIRE" le /proc/<pid>/environ, vous pouvez essayer
strings /proc/<pid>/environ
qui est meilleur que catça.
strings. Rester simple.
xargs --null.
tr '\0' '\n' < /proc/$$/environ | ...