Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

vie des variables d'environnement

10 réponses
Avatar
mpg
Bonsoir,

Je me pose des questions existentielles sur les conditions de vie des
variables d'environnement. En fait, une variable d'environnement, c'est
quoi vraiment ? Ça naît et ça meurt comment ?

Par exemple, dans un shell, y'a des variables définies, comme TERM ou
PS1, dont je me demande précisément d'où elles viennent : sont-ce des
options sur la ligne de commande qui lance le shell, y a-t'il un autre
mécanisme en jeu ? Pareil pour la conservation de variables comme TERM
quand on fait du ssh ou autre.

Ensuite, hors d'un shell (par exemple sous X), les applications ont-elles
accès à des variables d'environnement, et si oui, comment fixer leur
valeur (pas au moyen du .bashrc j'imagine) ?

Désolé si mes questions sont un peu floues, c'est que c'est pas très
clair dans ma tête, tout ça :)

Manuel.

10 réponses

Avatar
Luc.Habert.00__arjf
mpg :

Je me pose des questions existentielles sur les conditions de vie des
variables d'environnement. En fait, une variable d'environnement, c'est
quoi vraiment ?


Une string de la forme « fooºr » quelque part dans la mémoire d'un
process. Un process appelle la fonction « putenv » avec cette string en
argument, qui la stocke dans une table. Par la suite, quand le process
appelle la fonction « getenv » sur la string « foo », « getenv » va
rechercher dans la table et trouve cette string. Quand le process se
duplique via fork, la table est dupliquée comme toute la mémoire du process,
et les deux process résultants ont le même environnement. Enfin, quand un
process utilise l'appel « execve » pour remplacer son code par un nouveau
programme, il lui passe en argument un tableau d'environnement
(généralement, le sien), que le noyau va recopier dans la mémoire du
programme qu'il lance, à un endroit où le getenv du programme lancé va
regarder.


Par exemple, dans un shell, y'a des variables définies, comme TERM


TERM, il vient généralement de ce qui a lancé le shell. Par exemple, dans un
xterm, xterm forke, et dans le fils, avant d'exécuter le shell, il rajoute
« TERM=xterm » dans son environnement.

ou PS1


Là, ce n'est normalement pas une variable d'environnement, mais une variable
interne du shell. La différence est qu'elles ne sont pas transmises à
travers un execve. Dans un shell, quand tu fais un « fooºr », ça ne crée
normalement qu'une variable interne. Il faut dire « export foo » pour lui
dire d'en faire une variable d'environnement. Quand tu fais un « $foo », le
shell cherche « foo » à la fois dans son environnement et dans sa liste de
variables internes.

dont je me demande précisément d'où elles viennent : sont-ce des
options sur la ligne de commande qui lance le shell, y a-t'il un autre
mécanisme en jeu ?


Tous les process descendent à travers une série de fork et exec du premier
process lancé. Les environnements se voient ajouter ou retirer des variables
à diverses étapes en chemin...

Pareil pour la conservation de variables comme TERM quand on fait du ssh
ou autre.


Ça, c'est le client ssh qui transmet au sshd à l'autre bout une liste de
variables d'environnements, et ce dernier qui les ajoute dans son
environnement avant d'executer le shell.

Avatar
Greg
Bonsoir,

Je me pose des questions existentielles sur les conditions de vie des
variables d'environnement. En fait, une variable d'environnement, c'est
quoi vraiment ? Ça naît et ça meurt comment ?

Une variable d'environement est créée dans un processus "père" et

transmise a ces processus "fils" uniquement : ca veut dire que si tu
ouvre un terminal et que tu créé la variable TOTO, elle ne sera visible
que dans la fenetre terminal et dans tous les processus que tu va lancer
à partir de cette fenetre.

Par exemple, dans un shell, y'a des variables définies, comme TERM ou
PS1, dont je me demande précisément d'où elles viennent : sont-ce des
options sur la ligne de commande qui lance le shell, y a-t'il un autre
mécanisme en jeu ? Pareil pour la conservation de variables comme TERM
quand on fait du ssh ou autre.

Un certain nombre de variables sont définies dans des fichiers systemes

(comme /etc/profile). Ces fichiers sont "sourcés" dès le démarrage par
un processus très amont (donc père de bon nombres des processus qui
tourne après le démarrage ce qui explique que ces variables sont
toujours visibles)

Ensuite, hors d'un shell (par exemple sous X), les applications ont-elles
accès à des variables d'environnement, et si oui, comment fixer leur
valeur (pas au moyen du .bashrc j'imagine) ?
Si tu veux acceder a une variable d'environnement pour une appli X, le

plus simple est de faire un shell pour lancer cette appli :

export Ma_variable=TOTO
/usr/local/bin/Mon_executable

'Mon_executable' est alors un processus fils du script shell qui connait
'Ma_variable'.
L'avantage est que dès que tu ferme ton appli, la variable
d'environnement "Ma_variable" disparait et ne vient pas polluer le systeme.


Désolé si mes questions sont un peu floues, c'est que c'est pas très
clair dans ma tête, tout ça :)


Manuel.


Avatar
mpg
Le Thu, 17 May 2007 23:39:55 +0200, Greg a écrit:
Si tu veux acceder a une variable d'environnement pour une appli X, le
plus simple est de faire un shell pour lancer cette appli :

export Ma_variable=TOTO
/usr/local/bin/Mon_executable

'Mon_executable' est alors un processus fils du script shell qui connait
'Ma_variable'.
L'avantage est que dès que tu ferme ton appli, la variable
d'environnement "Ma_variable" disparait et ne vient pas polluer le
systeme.

Hm, en fait j'ai plutôt le désir inverse : j'aimerais bien que certaines

variables (LANG, PRINTER, etc.) soient vues par toutes les applis X.
D'après ce que j'ai compris, il faut donc que ces variables soient
définies au niveau du processus père de ces applis.

Quand je les lance depuis un shell, le shell doit être le processus père,
et il suffit que les variables soient positionnées dans mon .bashrc.
Quand je lance les applis depuis des boutons ou le menu de mon window
manager, j'imagine que c'est lui le père et qu'il faut donc positionner
les variables dans mon .xsession avant de lancer le wm. C'est bien ça ?

Avatar
Nicolas George
mpg wrote in message :
Quand je les lance depuis un shell, le shell doit être le processus père,
et il suffit que les variables soient positionnées dans mon .bashrc.
Quand je lance les applis depuis des boutons ou le menu de mon window
manager, j'imagine que c'est lui le père et qu'il faut donc positionner
les variables dans mon .xsession avant de lancer le wm. C'est bien ça ?


Exactement.

Sauf que .bashrc n'est pas exactement le bon endroit, ce serait plutôt
.bash_profile.

Avatar
mpg
Le Fri, 18 May 2007 12:38:09 +0000, Nicolas George a écrit:

Sauf que .bashrc n'est pas exactement le bon endroit, ce serait plutôt
.bash_profile.


C'est bien qu'on parle de ça, c'est justement une question que je me
posais :)

J'avais effectivement remarqué que le PATH, par exemple, est positionné
via le .bash_profile dans ma config par défaut. Or ça me semble
problématique, car quand j'ouvre un xterm, je constate que je n'ai pas
~/bin dans mon PATH alors que le .bash_profile est justement censé me
l'ajouter. Mais peut-être qu'il y a un problème ailleurs dans ma config ?

En tout cas, je suis preneur de toute explication concernant la
différence entre .bashrc et .bash_profile (il me semble que ça a à voir
avec la notion de shell de login que je n'ai jamais compris non plus) et
de ce qu'il convient de mettre dans l'un et pas dans l'autre.

Manuel.

Avatar
Nicolas George
mpg wrote in message :
En tout cas, je suis preneur de toute explication concernant la
différence entre .bashrc et .bash_profile (il me semble que ça a à voir
avec la notion de shell de login que je n'ai jamais compris non plus) et
de ce qu'il convient de mettre dans l'un et pas dans l'autre.


La réponse à tes interrogations est dans le man de bash, dans la partie
« invocation », sur une demi-page environ. En français là, par exemple

http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man1/bash.1.html#sect6

(je n'ai pas lu pour voir si la traduction était correcte).

Avatar
mpg
mpg wrote in message :
En tout cas, je suis preneur de toute explication concernant la
différence entre .bashrc et .bash_profile (il me semble que ça a à voir
avec la notion de shell de login que je n'ai jamais compris non plus) et
de ce qu'il convient de mettre dans l'un et pas dans l'autre.


La réponse à tes interrogations est dans le man de bash, dans la partie
« invocation », sur une demi-page environ. En français là, par exemple

http://www.linux-kheops.com/doc/man/manfr/man-html-0.9/man1/bash.1.html#sect6

Merci pour ce lien, même s'il ne répond pas vraiment à mes

interrogations. Je comprends qu'il y a deux catégories de shells
interactifs : ceux dits "de login", et les autres. Pour les premiers,
.bash_profile est exécuté, qui en général va aussi sourcer .bashrc, et
on quitte en disant logout. Pour les deuxièmes, seul .bashrc est lu, et
on quitte en disant exit.

Ce qui m'échappe encore, c'est la différence de principe qu'il y a entre
un shell de login et un pas-de-login, ou plus précisément la raison
d'être de cette distinction. Par exemple, quand j'ouvre un rxvt, j'ai un
shell pas-de-login, mon .bash_profile n'est pas lu, et mon PATH n'est
pas positionné pour inclure ~/bin. Je n'arrive désespérément pas à
comprendre pourquoi c'est bien qu'il en soit ainsi.

Manuel.


Avatar
Nicolas George
mpg wrote in message <464df4d1$0$14981$:
Ce qui m'échappe encore, c'est la différence de principe qu'il y a entre
un shell de login et un pas-de-login, ou plus précisément la raison
d'être de cette distinction.


Quand tu te connectes à une machine, tu as peut-être envie que quelques
messages te rappellent les courriers non-lus ou les rendez-vous du jour.
Mais tu ne veux pas ça à chaque fois que tu ouvres un terminal. Donc dans
.bash_profile, tu mets les commandes qui t'informent des nouveaux mails et
des rendez-vous, et dans .bashrc, tu mets ce qui configure le shell : alias,
apparence du prompt, complétion, etc.

Par exemple, quand j'ouvre un rxvt, j'ai un
shell pas-de-login, mon .bash_profile n'est pas lu, et mon PATH n'est
pas positionné pour inclure ~/bin.


Pour les sessions graphiques, c'est dans ~/.xsession ou équivalent qu'il
faut régler l'environnement. Si tu utilises fréquemment les deux, tu as tout
intérêt à regrouper l'environnement dans un seul fichier, qui est sourcé par
.xsession comme par .bash_profile.

Personnellement, j'utilise Zsh, qui a :

.zprofile, sourcé par les shells de login, qui est essentiellement vide pour
moi.

.zshrc, sourcé par les shells interactifs (y compris les shells de login),
qui contient les alias et les réglage de complétion, essentiellement.

.zshenv (sans équivalent chez bash), qui est sourcé par _tous_ les shells,
où je définis l'environnement, avec un test pour éviter de le redéfinir
s'il a déjà été défini, mais pour pouvoir quand même le redéfinir si je le
change.

Avatar
mpg
Le Fri, 18 May 2007 19:18:04 +0000, Nicolas George a écrit:

mpg wrote in message <464df4d1$0$14981$:
Ce qui m'échappe encore, c'est la différence de principe qu'il y a
entre un shell de login et un pas-de-login, ou plus précisément la
raison d'être de cette distinction.


Quand tu te connectes à une machine, tu as peut-être envie que quelques
messages te rappellent les courriers non-lus ou les rendez-vous du jour.
Mais tu ne veux pas ça à chaque fois que tu ouvres un terminal. Donc
dans .bash_profile, tu mets les commandes qui t'informent des nouveaux
mails et des rendez-vous, et dans .bashrc, tu mets ce qui configure le
shell : alias, apparence du prompt, complétion, etc.

Oki, là je comprends bien.


Par exemple, quand j'ouvre un rxvt, j'ai un
shell pas-de-login, mon .bash_profile n'est pas lu, et mon PATH n'est
pas positionné pour inclure ~/bin.


Pour les sessions graphiques, c'est dans ~/.xsession ou équivalent qu'il
faut régler l'environnement. Si tu utilises fréquemment les deux, tu as
tout intérêt à regrouper l'environnement dans un seul fichier, qui est
sourcé par .xsession comme par .bash_profile.

Oki. Alors à la fac ça va bien j'ai un ~/.xsession, qui d'ailleurs pour

l'instant renseignait une partie du PATH lui-même et sourçait mon
~/.bashrc (ce qui est peut-être un peu goret du coup, c'est ça qui
m'incitait à mettre l'environnement dans le rc). Du coup je pense que je
vais y mettre de l'ordre.

Par contre chez moi pour l'instant j'ai pas de ~/.xsession, mon
gestionnaire de connections X lançant directement wmaker. J'imagine que
la marche à suivre est d'en créer un (à faire appeler par wdm), qui
réglera l'environnement puis lancera wmaker. (Ce dernier possède un
fichier autostart, mais d'après ce que j'ai compris, il sera exécuté trop
tard pour régler l'environnement...)

Personnellement, j'utilise Zsh, qui a :

.zprofile, sourcé par les shells de login, qui est essentiellement vide
pour moi.

.zshrc, sourcé par les shells interactifs (y compris les shells de
login), qui contient les alias et les réglage de complétion,
essentiellement.

.zshenv (sans équivalent chez bash), qui est sourcé par _tous_ les
shells, où je définis l'environnement, avec un test pour éviter de le
redéfinir s'il a déjà été défini, mais pour pouvoir quand même le
redéfinir si je le change.


Yep, ça m'a l'air très raisonnable comme architecture. Je pense que je
vais effectivement créer un fichier séparé pour l'environnement, à faire
sourcer par .bash_profile et .xsession. Au fait, ton test fonctionne
comment ?

Merci pour ton aide.

Manuel.


Avatar
Nicolas George
mpg wrote in message :
Oki. Alors à la fac ça va bien j'ai un ~/.xsession, qui d'ailleurs pour
Par contre chez moi pour l'instant j'ai pas de ~/.xsession, mon
gestionnaire de connections X lançant directement wmaker. J'imagine que
la marche à suivre est d'en créer un (à faire appeler par wdm), qui
réglera l'environnement puis lancera wmaker.


Oui, ça semble raisonnable. À part que la dernière fois que j'ai regardé,
wdm était une grosse merde.

Yep, ça m'a l'air très raisonnable comme architecture. Je pense que je
vais effectivement créer un fichier séparé pour l'environnement, à faire
sourcer par .bash_profile et .xsession.


Passe à zsh, tant que tu y es :-)

Au fait, ton test fonctionne
comment ?


[[ "$ZSHENV_USER" == $UID-1 ]] && return
export ZSHENV_USER=$UID-1

dans les deux premières lignes. Quand je modifie l'environnement et que je
veux que ce soit pris en compte, je change le 1 en 2, et tous les nouveaux
shells sont affectés. Et je mets l'UID dedans pour que l'environnement soit
ré-adapté quand je change d'UID.