Tutorial

Comment lire et configurer les variables d'environnement et de shell sous Linux

Linux BasicsMiscellaneous

Introduction

Au cours d'une interaction avec votre serveur via une session shell, shell compile de nombreuses informations pour déterminer son comportement et accéder aux ressources. Certains de ces réglages se font dans les paramètres de configuration, d'autres doivent être saisis par l'utilisateur.

Le shell assure notamment le suivi de tous ces paramètres et ces détails par le biais d'une zone qu'il gère, appelée environnement. L'environnement est une zone que le shell construit à chaque fois qu'il démarre une session qui contient des variables définissant les propriétés du système.

Dans ce guide, nous allons voir de quelle manière interagir avec l'environnement, lire ou configurer les variables d'environnement et de shell de manière interactive et via les fichiers de configuration.

Comment fonctionnent l'environnement et les variables d'environnement

Chaque fois qu'une session shell est lancée, un processus est mis en place pour collecter et rassembler les informations qui devraient être à la disposition du processus shell et de ses processus enfant. Il obtient les données de ces paramètres à partir d'un grand nombre de fichiers et paramètres différents qui se trouvent sur le système.

L'environnement fournit un moyen par lequel le processus shell peut obtenir ou configurer les paramètres et, à son tour, les transmettre à ses processus enfant.

L'environnement est implémenté en tant que chaînes qui représentent des paires de valeurs clé. Si la transmission comporte plusieurs valeurs, elles sont généralement séparées par un :. Chaque paire ressemblera généralement à ceci :

KEY=value1:value2:...

Si la valeur contient un white-space significatif, des guillemets sont utilisés :

KEY="value with spaces"

Dans ces scénarios, les clés sont des variables. Elles peuvent être de deux types différents : les variables d'environnement ou les variables de shell.

Les variables d'environnement sont des variables qui sont définies pour le shell en cours d'utilisation et héritées par tous les shells ou processus enfant. Les variables d'environnement servent à transmettre des informations dans les processus qui se déclenchent depuis le shell.

Les variables de shell sont des variables qui sont exclusivement contenues dans le shell dans lequel elles ont été configurées ou définies. Elles sont couramment utilisées pour garder un suivi des données éphémères, comme le répertoire actuellement utilisé.

Par convention, ces types de variables sont généralement définis par des majuscules. Cela aide les utilisateurs à distinguer les variables d'environnement dans d'autres contextes.

Impression des variables de shell et d'environnement

Chaque session de shell garde une trace de ses propres variables de shell et d'environnement. Nous pouvons y accéder de différentes façons.

Nous pouvons voir une liste de toutes nos variables d'environnement en utilisant les commandes env ou printenv. Dans leur état par défaut, elles devraient fonctionner exactement de la même manière :

  • printenv
Output
SHELL=/bin/bash TERM=xterm USER=demouser LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca:... MAIL=/var/mail/demouser PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games PWD=/home/demouser LANG=en_US.UTF-8 SHLVL=1 HOME=/home/demouser LOGNAME=demouser LESSOPEN=| /usr/bin/lesspipe %s LESSCLOSE=/usr/bin/lesspipe %s %s _=/usr/bin/printenv

Ceci est assez typique pour la sortie à la fois de printenv et env. La différence entre les deux commandes ne se voit que dans leur fonctionnalité plus spécifique. Par exemple, avec printenv, vous pouvez demander les valeurs de variables individuelles :

  • printenv SHELL
Output
/bin/bash

En revanche, env vous permet de modifier l'environnement dans lequel les programmes s'exécutent en transmettant un ensemble de définitions de variables par le biais d'une commande, de la manière suivante :

  • env VAR1="value" command_to_run command_options

Étant donné que, comme nous l'avons appris précédemment, les processus enfant héritent généralement des variables d'environnement du processus parent, vous pouvez remplacer les valeurs ou ajouter des variables supplémentaires à l'enfant.

Comme vous pouvez le constater à partir du résultat de notre commande printenv, de nombreuses variables d'environnement sont configurées par les fichiers et les processus de notre système sans rien à saisir.

Ces dernières montrent les variables d'environnement, mais comment consulter les variables de shell ?

Pour cela, vous pouvez utiliser la commande set. Si nous saisissons set sans aucun autre paramètre, nous obtiendrons une liste de toutes les variables de shell, variables d'environnement, variables locales et fonctions de shell :

  • set
Output
BASH=/bin/bash BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:login_shell:progcomp:promptvars:sourcepath BASH_ALIASES=() BASH_ARGC=() BASH_ARGV=() BASH_CMDS=() . . .

On se retrouve généralement avec une énorme liste. Il est vivement conseillé de les intégrer dans un programme de pagination afin de pouvoir traiter la quantité de résultats obtenus plus facilement :

  • set | less

La quantité d'informations supplémentaires que nous recevons est quelque peu déroutante. Nous n'avons probablement pas à connaître toutes les fonctions de bash configurées, par exemple.

Nous pouvons nettoyer le résultat en spécifiant que set devrait s'exécuter en mode POSIX, ce qui n'imprimera pas les fonctions de shell. Nous pouvons l'exécuter dans un sous-shell pour qu'il ne change pas notre environnement actuel :

  • (set -o posix; set)

Vous obtiendrez ainsi une liste de toutes les variables d'environnement et de shell configurées.

Nous pouvons tenter de comparer ce résultat avec celui obtenu avec les commandes env ou printenv afin d'obtenir une liste des variables de shell uniquement, mais cela risque d'être imparfait en raison des différentes façons dont ces commandes renverront les informations :

  • comm -23 <(set -o posix; set | sort) <(env | sort)

Il est probable que la liste contienne encore quelques variables d'environnement, car la commande set déclenche les valeurs citées, tandis que les commandes printenv et env ne citent pas les valeurs des chaînes de caractères.

Cela devrait vous donner une bonne idée des variables d'environnement et de shell qui se trouvent dans votre session.

Ces variables sont utilisées pour toute sorte de choses. Elles vous offrent une alternative pour configurer des valeurs persistantes pour la session entre les processus, sans avoir à écrire les modifications sur un fichier.

Variables d'environnement et de shell communes

Certaines variables d'environnement et de shell sont très utiles et souvent référencées. Voici quelques variables d'environnement communes que vous allez rencontrer :

  • SHELL : cette variable décrit le shell qui interprétera les commandes que vous saisissez. Dans la plupart des cas, il s'agira de bash par défaut, mais d'autres valeurs peuvent être configurées si vous préférez utiliser d'autres options.
  • TERM : cette variable spécifie le type de terminal à émuler à l'exécution du shell. Il est possible d'émuler différents terminaux de matériel pour différentes exigences d'exploitation. Cependant, de manière générale, vous n'aurez pas à vous soucier de cela.
  • USER : l'utilisateur actuellement connecté.
  • PWD : le répertoire de travail en cours d'exécution.
  • OLDPWD : le précédent répertoire utilisé. Il est conservé par le shell afin de pouvoir revenir au précédent répertoire en exécutant cd-.
  • LS_COLORS : cette variable définit les codes de couleurs qui vous servent à ajouter une couleur aux résultats obtenus avec la commande ls. Elle vous permet de distinguer les différents types de fichiers et donne de plus amples informations à l'utilisateur en un coup d'œil.
  • MAIL : le chemin vers la boîte de réception de l'utilisateur en cours.
  • PATH : une liste des répertoires que le système vérifiera lorsque vous recherchez des commandes. Lorsqu'un utilisateur saisit une commande, le système vérifiera les répertoires dans cet ordre pour l'exécutable.
  • LANG : les paramètres actuels de langue et de localisation, y compris le codage de caractères.
  • HOME : le répertoire d'accueil de l'utilisateur actuellement connecté.
  • _ : la plus récente des précédentes commandes exécutées.

En plus de ces variables d'environnement, vous verrez souvent les variables de shell suivantes :

  • BASHOPTS : la liste des options qui ont été utilisées lorsque bash a été exécuté. Cette variable peut s'avérer utile pour savoir si l'environnement de shell fonctionne de la manière dont vous le souhaitez.
  • BASH_VERSION : la version de bash en cours d'exécution, dans un format lisible par l'humain.
  • BASH_VERSINFO : la version de bash en cours d'exécution, dans un format lisible par une machine.
  • COLUMNS : le nombre de colonnes larges qui servent à dessiner le résultat à l'écran.
  • DIRSTACK : la pile des répertoires qui sont disponibles avec les commandes pushd et popd.
  • HISTFILESIZE : le nombre de lignes d'historique de commande enregistrées dans un fichier.
  • HISTSIZE : le nombre de lignes d'historique de commandes autorisées en mémoire.
  • HOSTNAME :le nom d'hôte de l'ordinateur du moment.
  • IFS : le séparateur de champ interne utilisé pour séparer les entrées sur la ligne de commande. Un espace est utilisé par défaut.
  • PS1 : la configuration de l'invite de la commande principale. Cette variable sert à définir à quoi ressemble votre invite lorsque vous commencez une session de shell. La variable PS2 permet de déclarer des invites secondaires lorsqu'une commande s'étend sur plusieurs lignes.
  • SHELLOPTS : les options de shell qui peuvent être configurées avec l'option set.
  • UID : l'IUD de l'utilisateur actuellement connecté.

Configuration des variables de shell et d'environnement

Pour vous aider à mieux comprendre la différence entre les variables de shell et les variables d'environnement et vous présenter la syntaxe à utiliser pour ces variables, nous allons faire une petite démonstration.

Création de variables de shell

Nous allons commencer par configurer une variable de shell dans notre session en cours. Ceci est facile à réaliser, nous n'avons qu'à spécifier un nom et une valeur. Nous allons adhérer à la convention qui consiste à utiliser uniquement des majuscules pour le nom de la variable et à la configurer sur une chaîne simple.

  • TEST_VAR='Hello World!'

Ici, nous avons utilisé des guillemets, car la valeur de notre variable contient un espace. De plus, nous avons utilisé des guillemets simples, car le point d'exclamation est un caractère spécial dans le shell bash qui se développe généralement en historique bash si on n'en sort pas ou s'il n'est pas mis entre des guillemets simples.

Nous disposons maintenant d'une variable de shell. Cette variable est disponible dans notre session en cours, mais elle ne sera pas transmise aux processus enfant.

Nous pouvons voir cela en recherchant notre nouvelle variable dans le résultat de set :

  • set | grep TEST_VAR
Output
TEST_VAR='Hello World!'

Nous pouvons vérifier s'il ne s'agit pas d'une variable d'environnement en essayant la même méthode avec printenv :

  • printenv | grep TEST_VAR

Aucun résultat ne devrait être renvoyé.

Utilisons cela comme une opportunité de présenter un moyen d'accéder à la valeur de toute variable de shell ou d'environnement.

  • echo $TEST_VAR
Output
Hello World!

Comme vous pouvez le voir, vous faites référence à la valeur d'une variable en la faisant précéder d'un signe $. Le shell considère que cela signifie qu'il devrait substituer la valeur de la variable lorsqu'il la rencontre.

Nous disposons donc maintenant d'une variable de shell. Elle ne devrait être transmise à aucun processus enfant. Nous pouvons générer un shell bash new à partir de notre shell actuel pour le démontrer :

  • bash
  • echo $TEST_VAR

Si nous saisissons bash pour générer un shell enfant, puis tentons d'accéder ensuite au contenu de la variable, aucun résultat ne sera renvoyé. C'est ce à quoi nous nous attendions.

Revenont à notre shell d'origine en saisissant exit :

  • exit

Création de variables d'environnement

Maintenant, transformons notre variable de shell en variable d'environnement. Pour se faire, il faut exporter la variable. La commande qui permet de le faire se nomme à juste titre :

  • export TEST_VAR

Cela permettra de transformer notre variable en variable d'environnement. Nous pouvons vérifier cela en contrôlant à nouveau notre liste d'environnements :

  • printenv | grep TEST_VAR
Output
TEST_VAR=Hello World!

Cette fois, notre variable s'affiche. Recommençons notre expérience avec notre shell enfant :

  • bash
  • echo $TEST_VAR
Output
Hello World!

Super ! Notre shell enfant a reçu la variable définie par son parent. Avant de quitter ce shell enfant, essayons d'exporter une autre variable. Nous pouvons configurer les variables d'environnement en une seule étape, comme suit :

  • export NEW_VAR="Testing export"

Vérifiez qu'elle est bien exportée en tant que variable d'environnement :

  • printenv | grep NEW_VAR
Output
NEW_VAR=Testing export

Maintenant, retournons dans notre shell d'origine :

  • exit

Voyons si notre nouvelle variable est disponible :

  • echo $NEW_VAR

Aucun résultat n'est renvoyé.

En effet, les variables d'environnement ne sont transmises qu'aux processus enfant. Il n'existe pas de moyen intégré de configurer les variables d'environnement du shell parent. Ce qui est une bonne chose dans la plupart des cas. Cela empêche également les programmes de modifier l'environnement d'exploitation à partir duquel ils ont été appelés.

La variable NEW_VAR a été configurée comme une variable d'environnement dans notre shell enfant. Cette variable serait disponible pour elle-même et tous ses shells et processus enfant. Lorsque nous sommes revenus à notre shell principal, cet environnement a été détruit.

Rétrogradation et annulation des variables

Notre variable TEST-VAR est toujours définie comme une variable d'environnement. Nous pouvons la reconvertir en une variable de shell en saisissant :

  • export -n TEST_VAR

Il ne s'agit plus d'une variable d'environnement :

  • printenv | grep TEST_VAR

Cependant, il s'agit toujours d'une variable deshell :

  • set | grep TEST_VAR
Output
TEST_VAR='Hello World!'

Si nous voulons annuler complètement une variable, qu'elle soit de shell ou d'environnement, nous pouvons le faire avec la commande unset :

  • unset TEST_VAR

Nous pouvons vérifier qu'elle n'est plus configurée :

  • echo $TEST_VAR

Aucun résultat n'est renvoyé car la variable a été annulée.

Configuration de variables d'environnement à la connexion

Nous avons déjà mentionné que de nombreux programmes utilisent des variables d'environnement pour décider des spécificités de l'utilisation de ces variables. Nous ne voulons pas avoir à configurer d'importantes variables à chaque fois que nous lançons une nouvelle session shell. Nous avons d'ailleurs déjà vu combien de variables sont déjà configurées lors de la connexion. Alors, de quelle manière créer et configurer des variables automatiquement ?

Il s'agit en fait d'un problème plus complexe qu'il n'y paraît initialement, en raison des nombreux fichiers de configuration que le shell bash doit lire en fonction de la manière dont il est démarré.

La différence entre les sessions de shell Login, Non-Login, Interactive et Non-Interactive

Le shell bash lit différents fichiers de configuration en fonction de la façon dont la session est lancée.

Il existe une manière de distinguer les différentes sessions qui consiste à établir si le shell est généré comme une session de login ou non-login.

Un shell de login est une session de shell qui commence par l'authentification de l'utilisateur. Si vous vous connectez à une session via un terminal ou SSH et que vous vous authentifiez, votre session sera considérée comme un shell de login.

Si vous démarrez une nouvelle session shell à partir de votre session authentifiée, comme nous l'avons fait en appelant la commande bash à partir du terminal, une session shell de non-login sera lancée. Vos données d'authentification ne vous ont pas été demandées lorsque vous avez démarré votre shell enfant.

On peut également noter une autre distinction qui consiste à déterminer si une session de shell est interactive ou non-interactive.

Une session shell interactive est une session shell qui est rattachée à un terminal. Une session shell non-interactive est une session qui n'est pas rattachée à une session de terminal.

Donc, chaque session shell est classée comme étant de login ou non-login et interactive ou non-interactive.

Une session normale qui commence par SSH est généralement une session shell de login interactive. Un script exécuté à partir de la ligne de commande est généralement exécuté dans une session shell non-interactive et non-login. Une session de terminal peut être une combinaison de ces deux propriétés.

Que la session soit classée comme un shell de login ou non-login a des implications sur les fichiers à lire pour initialiser la session de shell.

Une session lancée par comme une session de login lira les détails de configuration tout d'abord à partir du fichier /etc/profile. Ensuite, elle recherchera le premier fichier de configuration de shell de login qui se trouve dans le répertoire d'accueil de l'utilisateur pour obtenir des détails de configuration spécifiques.

Elle lit le premier fichier qu'elle peut trouver sur ~/.bash_profile, ~/.bash_login et ~/.profile, et ne lit aucun autre fichier.

En revanche, une session définie comme un shell de non-login lira le fichier /etc/bash.bashrc puis ~/.bashrc spécifique à l'utilisateur pour créer son environnement.

Les shells non-interactifs lisent la variable d'environnement appelée BASH_ENV et lisent le fichier spécifié pour définir le nouvel environnement.

Implémentation de variables d'environnement

Comme vous pouvez le voir, il existe un grand nombre de fichiers différents que nous devrons généralement consulter pour placer nos paramètres.

Cela permet une grande flexibilité et nous sera d'une grande utilité dans des situations spécifiques, lorsque nous souhaiterons avoir certains paramètres dans un shell de login et d'autres paramètres dans un shell de non-login. Cependant, la plupart du temps nous voudrons avoir les mêmes paramètres dans les deux situations.

Heureusement, la plupart des distributions Linux configurent les fichiers de configuration de login pour obtenir les fichiers de configuration de non-login. Cela signifie que vous pouvez configurer les variables d'environnement que vous souhaitez avoir dans les deux à l'intérieur des fichiers de configuration de non-login. Ils seront ensuite lus dans les deux scénarios.

Nous configurerons généralement des variables d'environnement spécifiques à l'utilisateur et souhaiterons que nos réglages soient disponibles dans les deux shells, de login et de non-login. Cela signifie que l'endroit où configurer ces variables se trouve dans le fichier ~/.bashrc.

Maintenant, ouvrez ce fichier :

  • nano ~/.bashrc

Il est probable qu'il contienne déjà un certain nombre de données. La plupart des définitions ici servent à la configuration des options bash, qui ne sont pas liées à des variables d'environnement. Vous pouvez configurer les variables d'environnement comme vous le feriez avec la ligne de commande suivante :

  • export VARNAME=value

Toute nouvelle variable d'environnement peut être ajoutée n'importe où dans le fichier ~/.bashrc tant qu'elle n'est pas placée au milieu d'une autre commande ou pour une boucle. Ensuite, nous pouvons sauvegarder et fermer le fichier. La prochaine fois que vous lancerez une session de shell, la déclaration de votre variable d'environnement sera lue et transmise à l'environnement shell. Vous pouvez forcer votre session actuelle à lire le fichier en saisissant ce qui suit :

  • source ~/.bashrc

Si vous devez configurer des variables à l'échelle du système, vous devriez éventuellement envisager de les ajouter à /etc/profile, /etc/bash.bashrc, ou /etc/environment.

Conclusion

Les variables d'environnement et de shell sont toujours présentes dans votre session shell et peuvent s'avérer très utiles. Il s'agit d'un moyen intéressant pour un processus parent de paramétrer les détails de configuration de ses processus enfant et de configurer des options en-dehors des fichiers.

Ce qui peut être très avantageux dans des situations spécifiques. Par exemple, certains mécanismes de déploiement dépendent des variables d'environnement pour configurer les données d'authentification. Ceci est utile, car vous n'avez pas besoin de la conserver dans des fichiers qui pourraient être vus par des tiers.

Il existe de nombreux autres scénarios, plus banals, mais plus courants, dans lesquels vous devrez lire ou modifier l'environnement de votre système. Avec ces outils et ces techniques, vous disposez d'une bonne base pour apporter ces modifications et les utiliser correctement.

Creative Commons License