Quand j'ai lu votre question, ma première pensée a été $SHLVL. Ensuite, j'ai vu que vous vouliez compter les vimniveaux
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 vimcommande. Vous devrez le faire pour chaque variante de vi/ vimque 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 commandmot 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 .bashrcfichier 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'essayercmdncmdnps
vim() { ( ((SHLVL++)); exec vim "$@");}
La execcommande est là pour empêcher le processus shell supplémentaire de rester en attente.
Mais, il y a un gotcha. Le traitement du shell SHLVLest quelque peu intuitif: au démarrage, le shell vérifie si SHLVLest 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 SHLVLdevriez 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 SHLVLseulement 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 execdans 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 vimniveaux
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, viewetc.) Le exportest nécessaire parce que VILVLn'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 VILVLtant 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 vimplace exec vimet laisser les choses suivantes SHLVL:
vim() { ( ((VILVL++)); command vim "$@");}
Préférence personnelle:
Vous voudrez peut-être renommer VILVLquelque 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 .profilefichier 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.
$SHLVLvariable (maintenue par plusieurs coquilles) correspond-elle à ce que vous recherchez?