Problème : Trouve combien de coquilles je suis.
Détails : J'ouvre beaucoup le shell de vim. Construire et exécuter et sortir. Parfois, j'oublie et ouvre un autre vim à l'intérieur, puis un autre shell. :(
Je veux savoir combien de coquilles je suis profondément, peut-être même l'avoir sur mon écran de coquille à tout moment. (Je peux gérer cette partie).
Ma solution : analyser l'arbre de processus et rechercher vim et bash / zsh et déterminer la profondeur du processus actuel.
Quelque chose comme ça existe déjà? Je n'ai rien trouvé.
$SHLVL
variable (maintenue par plusieurs coquilles) correspond-elle à ce que vous recherchez?fg
pour revenir en arrière, qui n'a pas ce problème.vim
peut être plus déroutant de disposer de plusieurs tâches arrêtées parallèlement que de disposer d'une pile de processus imbriqués. Au fait, je préfère avoir plusieurs fenêtres , je peux donc facilement basculer rapidement, mais je n’appellerais pas cela un problème XY simplement parce que je préfère un flux de travail différent.Réponses:
Quand j'ai lu votre question, ma première pensée a été
$SHLVL
. Ensuite, j'ai vu que vous vouliez compter lesvim
niveaux en plus des niveaux de coque. Un moyen simple de le faire est de définir une fonction shell:Cela augmentera automatiquement et silencieusement
SHLVL
chaque fois que vous taperez unevim
commande. Vous devrez le faire pour chaque variante devi
/vim
que vous utilisez déjà; par exemple,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, lecommand
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
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'essayer
cmdn
cmdn
ps
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 siSHLVL
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
, vousSHLVL
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 deSHLVL
lorsque vous faites unexec
:Alors
est un lavage; il incrémente
SHLVL
seulement pour le décrémenter à nouveau. Vous pourriez aussi bien direvim
, sans bénéfice d'une fonction.Pour résoudre ce problème, vous feriez
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):(et ainsi de suite pour
vi
,view
etc.) Leexport
est nécessaire parce queVILVL
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 enexport 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 à lacommand vim
placeexec vim
et laisser les choses suivantesSHLVL
: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 commedans votre
.profile
fichier ou fichier applicable. (Vous ne devriez probablement pas utiliser le nomSHLVL
, car cela provoquerait le chaos si vous utilisiez un shell compatibleSHLVL
.)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.
la source
ps
oupstree
, quand vous pouvez le faire avec des fonctions intégrées au shell.dash
a une expansion arithmétique.SHELL_LEVEL=$((SHELL_LEVEL + 1))
devrait être suffisant même si $ SHELL_LEVEL était précédemment non défini ou vide. Ce n'est que si vous devez être portable sur le shell Bourne que vous devez recourirexpr
, mais vous devez également le remplacer$(...)
par`..`
.SHELL_LEVEL=`expr "${SHELL_LEVEL:-0}" + 1`
bash
script à lire ~ / .bashrc par faire de stdin une socket par exemple), alors cela peut devenir un problème. C'est beaucoup de "si", mais il y a quelque chose à garder en tête (des données non normalisées dans un contexte arithmétique sont dangereuses)Vous pouvez compter autant de temps que nécessaire pour accéder à l'arborescence des processus jusqu'à ce que vous trouviez un responsable de session. Comme avec
zsh
Linux:Ou POSIXly (mais moins efficace):
Cela donnerait 0 pour le shell qui a été lancé par votre émulateur de terminal ou getty, et un de plus pour chaque descendant.
Il suffit de le faire une fois au démarrage. Par exemple avec:
dans votre
~/.zshrc
ou équivalent pour l'avoir dans votre invite.tcsh
et plusieurs autres coquilles (zsh
,ksh93
,fish
etbash
au moins) maintiennent une$SHLVL
variable qu'ils incrémenter au démarrage (et décrément avant d' exécuter une autre commande avecexec
( à moins queexec
c'est dans un sous - shell si elles ne sont pas buggé (mais beaucoup sont))). Cela ne fait que suivre la quantité d' imbrication de shell , pas de processus d'imbrication. De plus, le niveau 0 n'est pas garanti pour être le responsable de la session.la source
Utilisez
echo $SHLVL
. Utilisez le principe KISS . Selon la complexité de votre programme, cela peut être suffisant.la source
bash
, mais pas pourdash
.Une solution potentielle consiste à examiner le résultat de
pstree
. Lorsqu'elle est exécutée à l'intérieur d'un shell créé de l'intérieurvi
, la partie de l'arborescence répertoriéepstree
doit indiquer votre profondeur. Par exemple:la source
Première variante - profondeur de la coque uniquement.
Solution simple pour
bash
: ajouter aux.bashrc
deux lignes suivantes (ou modifier votrePS1
valeur actuelle ):Résultat:
Le nombre au début de la chaîne d'invite sera le niveau du shell.
Deuxième variante, avec les niveaux imbriqués vim et shell.
ajouter ces lignes à la
.bashrc
Résultat:
v: 1 - niveau de profondeur vim
s: 3 - niveau de profondeur de coque
la source
Dans la question que vous avez mentionné l'analyse de
pstree
. Voici un moyen relativement simple:Les
pstree
options:-A
- Sortie ASCII pour un filtrage plus facile (dans notre cas, chaque commande est précédée de`-
)-a
- affiche également les arguments de la commande. En tant qu'effet secondaire, chaque commande est affichée sur une ligne séparée et nous pouvons facilement filtrer le résultat en utilisantgrep
-l
- ne pas tronquer les longues lignes-s
- montrer aux parents du processus sélectionné(malheureusement pas supporté dans les anciennes versions de
pstree
)$$
- le processus sélectionné - le PID du shell actuella source
Cela ne répond pas strictement à la question, mais dans de nombreux cas, il peut être inutile de le faire:
Lorsque vous lancez votre shell pour la première fois, lancez
set -o ignoreeof
. Ne le mets pas dans ton~/.bashrc
.Prenez l'habitude de taper Ctrl-D lorsque vous pensez être dans le shell de niveau supérieur et que vous voulez en être sûr.
Si vous n'êtes pas dans le shell de niveau supérieur, Ctrl-D signalera "la fin de l'entrée" au shell actuel et vous reculerez d'un niveau.
Si vous êtes dans le shell de niveau supérieur, vous recevrez un message:
Je l’utilise tout le temps pour les sessions SSH chaînées, afin de faciliter le retour à un niveau spécifique de la chaîne SSH. Cela fonctionne aussi bien pour les coquilles imbriquées.
la source