GNU/Linux >> Tutoriels Linux >  >> Linux

Quelle est la meilleure façon Distro/shell-agnostic pour définir des variables d'environnement ?

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 alternative VAR 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

Connexe :Comment configurer une combinaison de touches à l'échelle du système pour basculer un paramètre spécifique des Préférences Système ("Appuyer pour cliquer") ?

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.


Linux
  1. Comment définir/créer des variables d'environnement et de shell sous Linux

  2. La différence d'utilisation entre les variables shell et les variables d'environnement ?

  3. Quelle est la meilleure façon de compter le nombre de fichiers dans un répertoire ?

  4. Manière de récupérer le nom de l'environnement de bureau ? ?

  5. Existe-t-il un moyen de modifier les variables d'environnement d'un autre processus sous Unix ?

Comment définir une variable d'environnement dans Windows

Comment définir des variables d'environnement dans MacOS

Comment définir et répertorier les variables d'environnement sous Linux

Et la meilleure distribution de 2019 est ...

Comment définir et supprimer des variables d'environnement sous Linux

l'exécution crontab n'a pas les mêmes variables d'environnement que l'utilisateur exécutant