Quando ho letto la tua domanda, il mio primo pensiero è stato $SHLVL
. Poi ho visto che volevi contare i vim
livelli
oltre ai livelli di shell. Un modo semplice per farlo è definire una funzione shell:
vim() { ( ((SHLVL++)); command vim "$@");}
Ciò aumenterà automaticamente e silenziosamente SHLVL
ogni volta che si digita un vim
comando. Dovrai farlo per ogni variante di vi
/ vim
che tu abbia mai usato; per esempio,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
Il set esterno di parentesi crea una subshell, quindi la modifica manuale del valore di SHLVL
non contamina l'ambiente di shell corrente (parent). Naturalmente la command
parola chiave è lì per impedire alle funzioni di chiamarsi (il che si tradurrebbe in un ciclo di ricorsione infinito). E ovviamente dovresti inserire queste definizioni nel tuo .bashrc
o in un altro file di inizializzazione della shell.
C'è una leggera inefficienza in quanto sopra. In alcune conchiglie (bash essendo uno), se dici
( cmd 1 ; cmd 2 ; … ; cmd n )
dove c'è un programma esterno eseguibile (cioè non un comando integrato), la shell mantiene un processo aggiuntivo in giro, solo per aspettare che finisca . Questo (discutibilmente) non è necessario; i vantaggi e gli svantaggi sono discutibili. Se non ti dispiace legare un po 'di memoria e uno slot di processo (e vedere un processo di shell in più di quello che ti serve quando fai un ), fai quanto sopra e passa alla sezione successiva. Idem se stai usando una shell che non tiene il processo extra in giro. Ma, se vuoi evitare il processo extra, una prima cosa da provare ècmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
Il exec
comando è lì per impedire che il processo di shell extra persista.
Ma c'è un gotcha. La gestione della shell SHLVL
è in qualche modo intuitiva: quando la shell si avvia, controlla se SHLVL
è impostata. Se non è impostato (o impostato su qualcosa di diverso da un numero), la shell lo imposta su 1. Se è impostato (su un numero), la shell aggiunge 1 ad esso.
Ma, secondo questa logica, se dici exec sh
, SHLVL
dovresti salire. Ma questo è indesiderabile, perché il tuo livello di shell reale non è aumentato. La shell gestisce questo sottraendo uno da SHLVL
quando si esegue 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
Così
vim() { ( ((SHLVL++)); exec vim "$@");}
è un lavaggio; aumenta SHLVL
solo per ridurlo di nuovo. Potresti anche solo dire vim
, senza il beneficio di una funzione.
Nota:
Secondo Stéphane Chazelas (che sa tutto) , alcune conchiglie sono abbastanza intelligenti da non farlo se si exec
trovano in una subshell.
Per risolvere questo, lo faresti
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Poi ho visto che volevi contare i vim
livelli indipendentemente dai livelli
della shell. Bene, lo stesso trucco esatto funziona (bene, con una piccola modifica):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(e così via per vi
, view
ecc) Il export
è necessaria perché VILVL
non è definito come variabile di ambiente di default. Ma non ha bisogno di far parte della funzione; puoi semplicemente dire export VILVL
come comando separato (nel tuo .bashrc
). E, come discusso sopra, se il processo di shell extra non è un problema per te, puoi fare command vim
invece exec vim
e lasciare SHLVL
da solo:
vim() { ( ((VILVL++)); command vim "$@");}
Preferenza personale:
potresti voler rinominare VILVL
qualcosa di simile VIM_LEVEL
. Quando guardo “ VILVL
”, mi fanno male gli occhi; non sanno dire se si tratta di un errore ortografico di "vinile" o di un numero romano malformato.
Se stai usando una shell che non supporta SHLVL
(es. Trattino), puoi implementarla tu stesso fintanto che la shell implementa un file di avvio. Fai qualcosa del genere
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
nel tuo .profile
o nel file applicabile. (Probabilmente non dovresti usare il nome SHLVL
, poiché ciò causerà il caos se dovessi iniziare a usare una shell che supporta SHLVL
.)
Altre risposte hanno risolto il problema dell'incorporamento dei valori della variabile di ambiente nel prompt della shell, quindi non lo ripeterò, in particolare dici che sai già come farlo.
$SHLVL
variabile (gestita da più shell) è ciò che stai cercando?