En fait, je ne savais pas qu'il existe deux types de variables différentes auxquelles je peux accéder à partir de la ligne de commande. Tout ce que je savais, c'est que je peux déclarer des variables comme:
foo="my dear friends"
bar[0]="one"
bar[1]="two"
bar[2]="three"
ou y accéder avec un signe $, comme:
echo $foo
echo ${bar[1]}
ou en utilisant des variables intégrées, comme:
echo $PWD
PATH=$PATH:"/usr/bin/myProg"
Maintenant, j'entends qu'il y a deux (au moins?) Types de variables: les variables shell et les variables d'environnement.
- Quel est le but d'avoir deux types différents?
- Comment savoir de quel type est une variable?
- Quels sont les usages typiques de chacun?
shell
command-line
environment-variables
sharkant
la source
la source
Réponses:
Les variables d'environnement sont une liste de
name=value
paires qui existent quel que soit le programme (shell, application, démon…). Ils sont généralement hérités par les processus enfants (créés par une séquencefork
/exec
): les processus enfants obtiennent leur propre copie des variables parentes.Les variables shell n'existent que dans le contexte d'un shell. Ils ne sont hérités que dans les sous-coques (c'est-à-dire lorsque le shell est bifurqué sans
exec
opération). Selon les fonctionnalités du shell, les variables peuvent être non seulement de simples chaînes comme celles de l'environnement, mais également des tableaux, des variables composées, des variables typées comme des nombres entiers ou à virgule flottante, etc.Lorsqu'un shell démarre, toutes les variables d'environnement qu'il hérite de son parent deviennent également des variables de shell (à moins qu'elles ne soient pas valides en tant que variables de shell et autres cas d'angle comme ceux
IFS
qui sont réinitialisés par certains shells), mais ces variables héritées sont marquées comme exportées 1 . Cela signifie qu'ils resteront disponibles pour les processus enfants avec la valeur potentiellement mise à jour définie par le shell. C'est également le cas des variables créées sous le shell et marquées comme exportées avec leexport
mot - clé.Les tableaux et autres variables de type complexe ne peuvent être exportés que si leur nom et leur valeur peuvent être convertis en
name=value
modèle, ou lorsqu'un mécanisme spécifique au shell est en place (par exemple:bash
exporte des fonctions dans l'environnement et certains shells exotiques, non POSIX commerc
etes
peut exporter des tableaux ).Ainsi, la principale différence entre les variables d'environnement et les variables de shell est leur portée: les variables d'environnement sont globales tandis que les variables de shell non exportées sont locales au script.
Notez également que les shells modernes (au moins
ksh
etbash
) prennent en charge une troisième portée de variables de shell. Les variables créées dans les fonctions avec letypeset
mot-clé sont locales à cette fonction (la façon dont la fonction est déclarée active / désactive cette fonctionnalité sousksh
et le comportement de persistance est différent entrebash
etksh
). Voir /unix//a/28349/25941 Cela vaut pour les coquilles modernes comme
ksh
,dash
,bash
et similaire. Le shell Bourne hérité et les shells de syntaxe non Bourne commecsh
ont des comportements différents.la source
execve()
appel système et sont donc (généralement) utilisées pour conserver les données lors de l' exécution d'autres commandes (dans le même processus).IFS
dans certains shells).rc
,es
peuvent exporter des tableaux en utilisant un encodage adhoc.bash
etrc
peut également exporter des fonctions à l'aide de variables d'environnement (là encore, en utilisant un encodage spécial).ksh93
,typeset
restreint la portée uniquement dans les fonctions déclarées avec lafunction foo { ...; }
syntaxe, pas avec lafoo() cmd
syntaxe Bourne ( ) (et sa portée statique n'est pas dynamique comme dans d'autres shells).Variables shell
Les variables shell sont des variables dont la portée se trouve dans la session shell actuelle, par exemple dans une session shell interactive ou un script.
Vous pouvez créer une variable shell en attribuant une valeur à un nom inutilisé:
L'utilisation de variables shell est de garder une trace des données dans la session en cours. Les variables shell ont généralement des noms avec des lettres minuscules.
Variables d'environnement
Une variable d'environnement est une variable shell qui a été exportée. Cela signifie qu'elle sera visible en tant que variable, non seulement dans la session shell qui l'a créée, mais aussi pour tout processus (pas seulement les shells) démarré à partir de cette session.
ou
Une fois qu'une variable shell a été exportée, elle reste exportée jusqu'à ce qu'elle ne soit pas définie, ou jusqu'à ce que sa "propriété d'exportation" soit supprimée (avec
export -n
inbash
), il n'est donc généralement pas nécessaire de la réexporter. La suppression d'une variable avec launset
supprime (que ce soit une variable d'environnement ou non).Les tableaux et les hachages associatifs dans
bash
et d'autres shells ne peuvent pas être exportés pour devenir des variables d'environnement. Les variables d'environnement doivent être de simples variables dont les valeurs sont des chaînes, et elles ont souvent des noms composés de lettres majuscules.L'utilisation de variables d'environnement permet de garder une trace des données dans la session shell actuelle, mais aussi de permettre à tout processus démarré de prendre partie de ces données. Le cas typique de ceci est la
PATH
variable d'environnement, qui peut être définie dans le shell et utilisée plus tard par n'importe quel programme qui veut démarrer des programmes sans spécifier un chemin complet vers eux.La collection de variables d'environnement dans un processus est souvent appelée "l'environnement du processus". Chaque processus a son propre environnement.
Les variables d'environnement ne peuvent être "transférées", c'est-à-dire qu'un processus enfant ne peut jamais modifier les variables d'environnement dans son processus parent, et autre que la configuration de l'environnement pour un processus enfant au démarrage, un processus parent ne peut pas modifier l'environnement existant d'un processus enfant.
Les variables d'environnement peuvent être répertoriées avec
env
(sans aucun argument). En dehors de cela, elles apparaissent de la même manière que les variables shell non exportées dans une session shell. C'est un peu spécial pour le shell car la plupart des autres langages de programmation ne mélangent généralement pas les variables "ordinaires" avec les variables d'environnement (voir ci-dessous).env
peut également être utilisé pour définir les valeurs d'une ou plusieurs variables d'environnement dans l'environnement d'un processus sans les définir dans la session en cours:Cela commence
make
avec la variable d'environnementCC
définie sur la valeurclang
etCXX
définie surclang++
.Il peut également être utilisé pour nettoyer l'environnement d'un processus:
Cela commence ,
bash
mais ne transfère pas l'environnement actuel au nouveaubash
processus (il faudra encore avoir des variables d'environnement car elle crée de nouvelles de ses scripts d'initialisation du shell).Exemple de différence
Autres langues
Il existe des fonctions de bibliothèque dans la plupart des langages de programmation qui permettent d'obtenir et de définir les variables d'environnement. Notez que puisque les variables d'environnement sont stockées comme une simple relation clé-valeur, elles ne sont généralement pas des "variables" du langage. Un programme peut récupérer la valeur (qui est toujours une chaîne de caractères) correspondant à une clé (le nom de la variable d'environnement), mais devra ensuite la convertir en un entier ou quel que soit le type de données que la langue attend de la valeur.
En C, les variables d' environnement sont accessibles en utilisant
getenv()
,setenv()
,putenv()
etunsetenv()
. Les variables créées avec ces routines sont héritées de la même manière par tout processus que le programme C démarre.D'autres langages peuvent avoir des structures de données spéciales pour accomplir la même chose, comme le
%ENV
hachage en Perl, ou leENVIRON
tableau associatif dans la plupart des implémentations deawk
.la source
getenv()
,setenv()
,putenv()
etunsetenv()
. Les variables créées avec ces routines sont héritées de la même manière par tout processus que le programme C démarre. D'autres langues peuvent avoir des structures de données spéciales pour la même chose, comme%ENV
en Perl.exec*()
famille de fonctions peut également définir l'environnement du processus en cours d'exécution.Les variables shell sont difficiles à dupliquer.
Les variables d'environnement peuvent cependant être dupliquées; ils ne sont qu'une liste, et une liste peut avoir des entrées en double. Voici
envdup.c
pour cela.Que nous pouvons compiler et exécuter en disant
envdup
ensuiteenv
pour nous montrer quelles variables d'environnement sont définies ...Cela n'est peut-être utile que pour trouver des bogues ou autres bizarreries dans la gestion des programmes
**environ
.On dirait que Python 3.6 ici passe aveuglément le long des doublons (une abstraction qui fuit) alors que Perl 5.24 ne le fait pas. Et les coquilles?
Mon Dieu, que se passe-t-il si
sudo
ne désinfecte que la première entrée d'environnement maisbash
s'exécute ensuite avec la seconde? BonjourPATH
ouLD_RUN_PATH
exploiter. Votresudo
(et tout le reste ?) Est corrigé pour ce trou ? Les failles de sécurité ne sont ni "une différence anecdotique" ni juste "un bug" dans le programme appelant.la source
Une variable d'environnement est comme une variable shell , mais elle n'est pas spécifique au shell . Tous les processus sur les systèmes Unix ont un stockage variable d'environnement . La principale différence entre les variables d'environnement et de shell est que le système d' exploitation transmet toutes les variables d'environnement de votre shell aux programmes que le shell exécute, tandis que les variables de shell ne sont pas accessibles dans les commandes que vous exécutez.
env –
La commande vous permet d'exécuter un autre programme dans un environnement personnalisé sans modifier celui en cours. Lorsqu'il est utilisé sans argument, il affichera une liste des variables d'environnement actuelles.printenv –
La commande imprime toutes ou les variables d'environnement spécifiées.set –
La commande définit ou supprime les variables shell. Lorsqu'il est utilisé sans argument, il affichera une liste de toutes les variables, y compris les variables d'environnement et de shell, et les fonctions de shell.unset –
La commande supprime le shell et les variables d'environnement.export –
La commande définit les variables d'environnementla source