La question dit tout. J'utilise actuellement Arch Linux et le zsh, mais j'aimerais une solution qui (au minimum) fonctionne à la fois sur les VT et dans les xterms et aussi (espérons-le, de préférence) continuera à fonctionner si je change de distribution ou de shell.
J'ai entendu des réponses extrêmement disparates à cette question dans la documentation de différentes distributions. Ubuntu dit "utiliser .pam_environment". Je pense que dans Arch, ce qu'ils recommandent dépend de votre shell. Actuellement, je mets tout dans .profile et si un shell ne le source pas pour une raison quelconque (par exemple bash si .bash_profile existe), je remplace cela en le recherchant manuellement. Mais il semble qu'il doit y avoir un meilleur moyen.
Réponse acceptée :
Il n'existe malheureusement pas d'emplacement entièrement portable pour définir les variables d'environnement. Les deux fichiers qui se rapprochent le plus sont ~/.profile
, qui est l'emplacement traditionnel et fonctionne immédiatement sur de nombreuses configurations, et ~/.pam_environment
, une alternative moderne, banale mais limitée.
Que mettre dans ~/.pam_environment
Le fichier ~/.pam_environment
est lu par toutes les méthodes de connexion qui utilisent PAM et qui ont ce fichier activé. Cela couvre la plupart des systèmes Linux de nos jours.
L'avantage majeur de ~/.pam_environment
est que (lorsqu'il est activé), il est lu avant le démarrage du shell de l'utilisateur, il fonctionne donc quel que soit le type de session, le shell de connexion et d'autres complexités. Cela fonctionne même pour les connexions non interactives telles que su -c somecommand
et ssh somecommand
.
La principale limitation de ~/.pam_environment
est que vous ne pouvez y mettre que des affectations simples, pas une syntaxe shell complexe. La syntaxe de ce fichier est la suivante.
- Les fichiers sont analysés ligne par ligne.
- Chaque ligne doit avoir la forme
VAR=VALUE
où VAR se compose de lettres, de chiffres et de traits de soulignement. La forme alternativeVAR DEFAULT=value
permet l'expansion des variables d'environnement à l'aide de${VAR}
syntaxe et les variables spéciales@{HOME}
et@{SHELL}
. #
commence un commentaire, il ne peut pas apparaître dans une valeur.- Si VALUE est entouré de
"
, alors VAR est défini sur la chaîne entre les guillemets. $
ou@
insérez un$
littéral ou@
et les longues lignes peuvent être divisées en échappant la nouvelle ligne avec un.
- S'il y a une erreur de syntaxe telle que no
=
ou un espace blanc sans guillemets, la variable est supprimée de l'environnement.
Donc, du côté positif, ~/.pam_environment
fonctionne dans un large éventail de circonstances. En revanche, vous ne pouvez pas utiliser la sortie d'une commande (par exemple, tester si un répertoire ou un programme est présent), et certains caractères (#"
, retour à la ligne) sont impossibles ou gênants à mettre dans la valeur.
Que mettre dans ~/.profile
Ce fichier doit avoir une syntaxe sh portable (POSIX). Utilisez uniquement les extensions ksh ou bash (tableaux, [[ … ]]
, etc.) si vous savez que votre système a ces shells comme /bin/sh
.
Ce fichier peut être lu par des scripts dans des applications automatisées, il ne doit donc pas appeler de programmes qui produisent une sortie ou appeler exec
. Si vous souhaitez le faire sur les connexions en mode texte, faites-le uniquement pour les shells interactifs. Exemple :
case $- in *i*)
# Display a message if I have new mail
if mail -e; then echo 'You have new mail'; fi
# If zsh is available, and this looks like a text-mode login, run zsh
case "`ps $PPID` " in
*" login "*)
if type zsh >/dev/null 2>/dev/null; then exec zsh; fi;;
esac
esac
Ceci est un exemple d'utilisation de /bin/sh
comme shell de connexion et en passant à votre shell préféré. Voir aussi comment puis-je utiliser bash comme shell de connexion lorsque mon administrateur système refuse de me laisser le changer
Quand est ~/.profile
pas lu sur une connexion non graphique ?
Différents shells de connexion lisent différents fichiers.
Si votre shell de connexion est bash
Bash lit ~/.bash_login
ou ~/.bash_profile
s'ils existent à la place de ~/.profile
. De plus, bash ne lit pas ~/.bashrc
dans un shell de connexion même s'il est interactif. Pour ne plus jamais avoir à vous souvenir de ces bizarreries, créez un ~/.bash_profile
avec les deux lignes suivantes :
. ~/.profile
case $- in *i*) . ~/.bashrc;; esac
Si votre shell de connexion est zsh
Zsh lit ~/.zprofile
et ~/.zlogin
, mais pas ~/.profile
. Zsh a une syntaxe différente de sh, mais peut lire ~/.profile
en mode d'émulation sh. Vous pouvez l'utiliser pour votre ~/.zprofile
:
emulate sh -c '. ~/.profile'
Si votre shell de connexion est un autre shell
Vous ne pouvez pas y faire grand-chose, à moins d'utiliser /bin/sh
comme shell de connexion et votre shell préféré (comme le poisson) comme shell interactif uniquement. C'est ce que je fais avec zsh. Voir ci-dessus pour un exemple d'invocation d'un autre shell depuis ~/.profile
.
Commandes à distance
Lors de l'appel d'une commande à distance sans passer par un shell interactif, tous les shells ne lisent pas un fichier de démarrage.
Ksh lit le fichier spécifié par ENV
variable, si vous parvenez à la passer.
Bash lit ~/.bashrc
s'il n'est pas interactif (!) et son processus parent est appelé rshd
ou sshd
. Vous pouvez donc démarrer votre ~/.bashrc
avec
if [[ $- != *i* ]]; then
. ~/.profile
return
fi
Zsh lit toujours ~/.zshenv
quand ça commence. À utiliser avec prudence, car ceci est lu par chaque instance de zsh, même s'il s'agit d'un sous-shell dans lequel vous avez défini d'autres variables. Si zsh est votre shell de connexion et que vous souhaitez l'utiliser pour définir des variables uniquement pour les commandes distantes, utilisez une protection :définissez une variable dans ~/.profile
, comme MY_ENVIRONMENT_HAS_BEEN_SET=yes
, et vérifiez cette garde avant de lire ~/.profile
.
if [[ -z $MY_ENVIRONMENT_HAS_BEEN_SET ]]; then emulate sh -c '~/.profile'; fi
Le cas des logins graphiques
De nombreuses distributions, gestionnaires d'affichage et environnements de bureau s'arrangent pour exécuter ~/.profile
, soit en le recherchant explicitement à partir des scripts de démarrage, soit en exécutant un shell de connexion.
Malheureusement, il n'existe pas de méthode générale pour gérer les combinaisons distribution/DM/DE où ~/.profile
n'est pas lu.
Si vous utilisez une session traditionnelle démarrée par ~/.xsession
, c'est l'endroit où vous devez définir vos variables d'environnement ; faites-le en vous procurant ~/.profile
(c'est-à-dire . ~/.profile
). Notez que dans certaines configurations, les scripts de démarrage de l'environnement de bureau sourceront ~/.profile
à nouveau.