Quand j'ai lu votre question, ma première pensée a été $SHLVL
. Ensuite, j'ai vu que vous vouliez compter les vim
niveaux
en plus des niveaux de coque. Un moyen simple de le faire est de définir une fonction shell:
vim() { ( ((SHLVL++)); command vim "$@");}
Cela augmentera automatiquement et silencieusement SHLVL
chaque fois que vous taperez une vim
commande. Vous devrez le faire pour chaque variante de vi
/ vim
que vous utilisez déjà; par exemple,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
L'ensemble de parenthèses externe crée un sous-shell, de sorte que la modification manuelle de la valeur de SHLVL
ne contamine pas l'environnement de coque actuel (parent). Bien sûr, le command
mot clé est là pour empêcher les fonctions de s’appeler (ce qui entraînerait une boucle de récursion infinie). Et bien sûr, vous devriez mettre ces définitions dans votre .bashrc
fichier d'initialisation du shell ou dans un autre.
Il y a une légère inefficacité dans ce qui précède. Dans certains coquillages (bash étant un), si vous dites
( cmd 1 ; cmd 2 ; … ; cmd n )
où est un programme exécutable externe (c.-à-d., pas une commande intégrée), le shell garde un processus supplémentaire traîner, juste pour attendre la fin. Ce n'est (sans doute) pas nécessaire; les avantages et les inconvénients sont discutables. Si cela ne vous dérange pas de garder un peu de mémoire et un emplacement de processus (et de voir un processus shell plus que nécessaire en a ), faites ce qui précède et passez à la section suivante. Idem si vous utilisez un shell qui ne laisse pas traîner le processus supplémentaire. Mais si vous voulez éviter le processus supplémentaire, la première chose à faire est d'essayercmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
La exec
commande est là pour empêcher le processus shell supplémentaire de rester en attente.
Mais, il y a un gotcha. Le traitement du shell SHLVL
est quelque peu intuitif: au démarrage, le shell vérifie si SHLVL
est défini. S'il n'est pas défini (ou défini sur autre chose qu'un nombre), le shell le définit sur 1. S'il est défini (sur un nombre), le shell ajoute 1 à celui-ci.
Mais, par cette logique, si vous dites exec sh
, vous SHLVL
devriez monter. Mais ce n'est pas souhaitable, car votre niveau de coque réel n'a pas augmenté. Le shell gère cela en soustrayant un de SHLVL
lorsque vous faites un exec
:
$ echo "$SHLVL"
1
$ set | grep SHLVL
SHLVL=1
$ env | grep SHLVL
SHLVL=1
$ (env | grep SHLVL)
SHLVL=1
$ (env) | grep SHLVL
SHLVL=1
$ (exec env) | grep SHLVL
SHLVL=0
Alors
vim() { ( ((SHLVL++)); exec vim "$@");}
est un lavage; il incrémente SHLVL
seulement pour le décrémenter à nouveau. Vous pourriez aussi bien dire vim
, sans bénéfice d'une fonction.
Note:
Selon Stéphane Chazelas (qui sait tout) , certains obus sont suffisamment intelligents pour ne pas le faire s’ils se trouvent exec
dans un sous-shell.
Pour résoudre ce problème, vous feriez
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Ensuite, j'ai vu que vous vouliez compter les vim
niveaux
indépendamment des niveaux de coque. Eh bien, le même truc fonctionne (bien, avec une modification mineure):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(et ainsi de suite pour vi
, view
etc.) Le export
est nécessaire parce que VILVL
n'est pas définie comme une variable d'environnement par défaut. Mais cela n’a pas besoin de faire partie de la fonction; vous pouvez simplement dire en export VILVL
tant que commande séparée (dans votre .bashrc
). Et, comme indiqué ci-dessus, si le processus de shell supplémentaire ne vous pose pas problème, vous pouvez le faire à la command vim
place exec vim
et laisser les choses suivantes SHLVL
:
vim() { ( ((VILVL++)); command vim "$@");}
Préférence personnelle:
Vous voudrez peut-être renommer VILVL
quelque chose comme VIM_LEVEL
. Quand je regarde “ VILVL
”, j'ai mal aux yeux; ils ne peuvent pas dire s'il s'agit d'une mauvaise orthographe de «vinyle» ou d'un chiffre romain mal formé.
Si vous utilisez un shell qui ne prend pas en charge SHLVL
(par exemple, dash), vous pouvez l'implémenter vous-même, à condition que le shell implémente un fichier de démarrage. Juste faire quelque chose comme
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
dans votre .profile
fichier ou fichier applicable. (Vous ne devriez probablement pas utiliser le nom SHLVL
, car cela provoquerait le chaos si vous utilisiez un shell compatible SHLVL
.)
D'autres réponses ont abordé la question de l'intégration de valeurs de variable d'environnement dans votre invite de shell, je ne vais donc pas le répéter, surtout si vous dites que vous savez déjà comment le faire.
$SHLVL
variable (maintenue par plusieurs coquilles) correspond-elle à ce que vous recherchez?