Cuando leí tu pregunta, mi primer pensamiento fue $SHLVL
. Entonces vi que querías contar vim
niveles
además de los niveles de shell. Una manera simple de hacer esto es definir una función de shell:
vim() { ( ((SHLVL++)); command vim "$@");}
Esto aumentará automática y silenciosamente SHLVL
cada vez que escriba un vim
comando. Deberá hacer esto para cada variante de vi
/ vim
que alguna vez use; p.ej,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
El conjunto externo de paréntesis crea una subshell, por lo que el cambio manual en el valor de SHLVL
no contamina el entorno de shell actual (principal). Por supuesto, la command
palabra clave está allí para evitar que las funciones se llamen a sí mismas (lo que daría como resultado un bucle de recursión infinito). Y, por supuesto, debe poner estas definiciones en su .bashrc
u otro archivo de inicialización de shell.
Hay una leve ineficiencia en lo anterior. En algunas conchas (bash siendo uno), si dices
( cmd 1 ; cmd 2 ; … ; cmd n )
donde es un programa externo ejecutable (es decir, no un comando incorporado), el shell mantiene un proceso adicional por ahí, solo para esperar a que termine. Esto (posiblemente) no es necesario; Las ventajas y desventajas son discutibles. Si no le importa atar un poco de memoria y una ranura de proceso (y ver un proceso de shell más de lo que necesita cuando hace una ), haga lo anterior y pase a la siguiente sección. Lo mismo si estás usando un shell que no mantiene el proceso extra por ahí. Pero, si desea evitar el proceso adicional, lo primero que debe intentar escmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
El exec
comando está allí para evitar que el proceso de shell adicional se demore.
Pero, hay una trampa. El manejo del shell SHLVL
es algo intuitivo: cuando se inicia el shell, comprueba si SHLVL
está configurado. Si no está establecido (o establecido en algo que no sea un número), el shell lo establece en 1. Si está establecido (en un número), el shell agrega 1 a él.
Pero, según esta lógica, si dices exec sh
, SHLVL
deberías subir. Pero eso no es deseable, porque su nivel real de shell no ha aumentado. El shell maneja esto restando uno de SHLVL
cuando haces 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
Entonces
vim() { ( ((SHLVL++)); exec vim "$@");}
es un lavado; se incrementa SHLVL
solo para disminuirlo nuevamente. También podría decir vim
, sin el beneficio de una función.
Nota:
De acuerdo con Stéphane Chazelas (quien lo sabe todo) , algunos shells son lo suficientemente inteligentes como para no hacer esto si exec
están en un subshell.
Para arreglar esto, harías
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Entonces vi que querías contar los vim
niveles
independientemente de los niveles de shell. Bueno, exactamente el mismo truco funciona (bueno, con una pequeña modificación):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(y así sucesivamente para vi
, view
etc.) export
Es necesario porque VILVL
no está definido como una variable de entorno de forma predeterminada. Pero no necesita ser parte de la función; se puede decir simplemente export VILVL
con un comando aparte (en su .bashrc
). Y, como se discutió anteriormente, si el proceso de shell adicional no es un problema para usted, puede hacerlo en command vim
lugar de exec vim
dejarlo SHLVL
solo:
vim() { ( ((VILVL++)); command vim "$@");}
Preferencia personal:
es posible que desee cambiar el nombre VILVL
de algo como VIM_LEVEL
. Cuando miro a " VILVL
", me duelen los ojos; no pueden decir si se trata de un error ortográfico de "vinilo" o de un número romano mal formado.
Si está utilizando un shell que no es compatible SHLVL
(por ejemplo, guión), puede implementarlo usted mismo siempre que el shell implemente un archivo de inicio. Solo haz algo como
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
en su .profile
o archivo aplicable. (Probablemente no debería usar el nombre SHLVL
, ya que eso causará caos si alguna vez comienza a usar un shell que lo admita SHLVL
).
Otras respuestas han abordado el problema de incrustar valores variables de entorno en su indicador de shell, por lo que no repetiré eso, especialmente si usted dice que ya sabe cómo hacerlo.
$SHLVL
variable (mantenida por varios shells) lo que estás buscando?