Pourriez-vous expliquer les phrases suivantes du manuel de Bash à propos de $_ , en particulier les parties en gras, peut-être avec quelques exemples ?
Au démarrage du shell, définissez le chemin absolu utilisé pour
invoquer le shell ou le script shell en cours d'exécution comme transmis dans l'environnement
ou la liste d'arguments .Par la suite , se développe jusqu'au dernier argument de la commande
précédente, après développement.Également défini sur le chemin d'accès complet utilisé pour appeler chaque
commande exécutée et placé dans l'environnement exporté vers cette commande .Lors de la vérification du courrier , ce paramètre contient le nom du fichier courrier.
Réponse acceptée :
Je suis d'accord que ce n'est pas très clair.
1. Au démarrage du shell,
-
si le
_la variable était dans l'environnement quibashreçu , puisbashle laisse intact.En particulier, si ce
bashle shell a été invoqué par un autrebashshell (bien quezsh,yashet quelqueskshles implémentations le font aussi
), alors cebashshell aura défini le_variable d'environnement
au chemin de la commande en cours d'exécution (c'est le 3ème
point de votre question). Par exemple, sibashest invoqué pour
interpréter un script à la suite d'un autrebashinterprétant le shell :bash-script some argsCe
bashaura passé_=/path/to/bash-scripdans l'environnement
donné àbash-script, et c'est ce que la valeur
initiale du$_bashla variable sera dans lebashshell qui
interprète ce script.$ env -i _=whatever bash -c 'echo "$_"' whatever -
Maintenant, si l'application appelante ne passe pas un
_environnement
variable , lebashinvoqué le shell initialisera$_auargv[0]il reçoit
lui-même qui pourrait êtrebash, ou/path/to/bashou/path/to/some-scriptou toute autre chose (dans l'exemple ci-dessus, cela
serait/bin/bashsi le she-bang du script était#! /bin/bashou/path/to/bash-scriptselon le
système).Ce texte est donc trompeur car il décrit le comportement de
l'appelant quibashn'a aucun contrôle sur. L'application qui a appelébashpeut très bien ne pas définir$_du tout (en pratique, seuls certains
shells et quelques rares applications interactives le font,execlp()ne le fait pas
par exemple), ou il pourrait l'utiliser pour quelque chose de complètement différent
(par exempleksh93le définit sur*pid*/path/to/command).$ env bash -c 'echo "$_"' /usr/bin/env (env did not set it to /bin/bash, so the value we get is the one passed to env by my interactive shell) $ ksh93 -c 'bash -c "echo $_"' *20042*/bin/bash
2. Par la suite
Le Par la suite n'est pas très clair non plus. En pratique, c'est dès que bash interprète une commande simple dans l'environnement shell actuel.
-
Dans le cas d'un shell interactif , qui sera sur la première commande simple interprétée depuis
/etc/bash.bashrcpar exemple.Par exemple, à l'invite d'un shell interactif :
$ echo "$_" ] (the last arg of the last command from my ~/.bashrc) $ f() { echo test; } $ echo "$_" ] (the command-line before had no simple command, so we get the last argument of that previous echo commandline) $ (: test) $ echo "$_" ] (simple command, but in a sub-shell environment) $ : test $ echo "$_" test -
Pour un shell non interactif , ce serait la première commande dans
$BASH_ENVou du code fourni à ce shell si$BASH_ENVn'est pas
défini.
3. Quand Bash exécute une commande
Le troisième point est quelque chose de différent et est suggéré dans la discussion ci-dessus.
bash , comme quelques autres shells passeront un _ variable d'environnement aux commandes qu'il exécute qui contient le chemin que bash utilisé comme premier argument de execve() appels système.
$ env | grep '^_'
_=/usr/bin/env
4. Lors de la vérification du courrier
Le quatrième point est décrit plus en détail dans la description du MAILPATH variables :
‘CHEMIN DE COURRIER’
Une liste de noms de fichiers séparés par deux-points" que le shell vérifie périodiquement
pour l'arrivée de nouveaux messages .Chaque entrée de liste peut spécifier le message qui
est imprimé lorsqu'un nouveau courrier arrive dans le fichier courrier en séparant le
nom du fichier du message par un '?'.
Lorsqu'il est utilisé dans le texte du
message, '$_' se transforme en nom du fichier de courrier actuel.
Exemple :
$ MAILCHECK=1 MAILPATH='/tmp/a?New mail in <$_>' bash
bash$ echo test >> /tmp/a
New mail in </tmp/a>