Linux /proc/<pid>/environ
ne met pas à jour (si j'ai bien compris, le fichier contient l'environnement initial du processus).
Comment lire l' environnement actuel d' un processus ?
la source
Linux /proc/<pid>/environ
ne met pas à jour (si j'ai bien compris, le fichier contient l'environnement initial du processus).
Comment lire l' environnement actuel d' un processus ?
/proc/$pid/environ
met à 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 /proc
et 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' execve
appel 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=foo
dans 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
. Regardezassign_in_env
dansvariables.c
la source de bash, par exemple.fork
alors libc effectue l'sys_fork
appel à l'aide de l'environnement alloué par tas pour le processus enfant.argv
sont 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'
ptrace
appel système (par exemple, à l'aide degdb
) pour lire l'environnement à partir de lachar **__environ
variable 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 **__environ
spé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 GNUlibc
(glibc
) fait pour vous.Si le processus utilise
glibc
, il est conforme à POSIX. Après__environ
avoir été déclaré dansglibc//posix/environ.c
Glibc, il est initialisé__environ
avec un pointeur sur la mémoiremalloc
extraite du segment de mémoire du processus, puis copie l’environnement initial de la pile dans cette zone. Chaque fois que le processus utilise lasetenv
fonction,glibc
ne arealloc
pour ajuster la taille de la surface qui__environ
pointe vers pour tenir compte de la nouvelle valeur ou variable. (Vous pouvez télécharger le code source de glibc avecgit clone git://sourceware.org/git/glibc.git glibc
). Pour bien comprendre le mécanisme, vous devrez également lire le code Hurd danshurd//init/init.c:frob_kernel_process()
(git clone git: //git.sv.gnu.org/hurd/hurd.git hurd).Maintenant , si le nouveau processus
fork
n'ed, sans suiteexec
écraser la pile, l'argument et l' environnement magique de la copie se fait danslinux//kernel/fork.c:do_fork(...)
, où lescopy_process
appels de routinedup_task_struct
qui attribue la pile du nouveau processus en appelantalloc_thread_info_node
, qui appellesetup_thread_stack
(linux//include/linux/sched.h
) pour le nouveau processus à l' aidealloc_thread_info_node
.Enfin, la
__environ
convention 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 utiliserglibc
et sans le__environ
global, 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 wrapperssys_exec
. Il est probable que personne ne sera en mesure de deviner où vous mettez les changements dans votre environnement.la source
/proc/[pid]/
semblent avoir un encodage étrange (quelqu'un d'autre peut savoir quoi et pourquoi). Pour moi, ilcat environ
suffirait d’imprimer les variables d’environnement dans un format très difficile à lire.cat environ | strings
ré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
environ
fichier n'est pas mis à jour pour le processus dans son répertoire de processus sous / proc filesystem?ou
ou
Ce qui précède imprimera les variables d’environnement du processus au
ps
format 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):
ou
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/environ
fichier.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.
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.
la source
export foo=bar
dans la session de one bash (pid xxxx), puiscat /proc/xxxx/environ | tr \\0 \\n
dans la session de l'autre bash et je ne vois pasfoo
.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 essayerqui est meilleur que
cat
ça.la source
strings
. Rester simple.xargs --null
.tr '\0' '\n' < /proc/$$/environ | ...