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 quibash
reçu , puisbash
le laisse intact.En particulier, si ce
bash
le shell a été invoqué par un autrebash
shell (bien quezsh
,yash
et quelquesksh
les implémentations le font aussi
), alors cebash
shell 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, sibash
est invoqué pour
interpréter un script à la suite d'un autrebash
interprétant le shell :bash-script some args
Ce
bash
aura passé_=/path/to/bash-scrip
dans l'environnement
donné àbash-script
, et c'est ce que la valeur
initiale du$_
bash
la variable sera dans lebash
shell qui
interprète ce script.$ env -i _=whatever bash -c 'echo "$_"' whatever
-
Maintenant, si l'application appelante ne passe pas un
_
environnement
variable , lebash
invoqué le shell initialisera$_
auargv[0]
il reçoit
lui-même qui pourrait êtrebash
, ou/path/to/bash
ou/path/to/some-script
ou toute autre chose (dans l'exemple ci-dessus, cela
serait/bin/bash
si le she-bang du script était#! /bin/bash
ou/path/to/bash-script
selon le
système).Ce texte est donc trompeur car il décrit le comportement de
l'appelant quibash
n'a aucun contrôle sur. L'application qui a appelébash
peut 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 exempleksh93
le 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.bashrc
par 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_ENV
ou du code fourni à ce shell si$BASH_ENV
n'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>