Quando leio sua pergunta, meu primeiro pensamento foi $SHLVL
.
Então vi que você queria contar vim
levels
além dos níveis de shell.
Uma maneira simples de fazer isso é definir uma função de shell:
vim() { ( ((SHLVL++)); command vim "$@");}
Isso incrementará automática e silenciosamente SHLVL
cada vez que você digita um comando vim
.
Você precisará fazer isso para cada variante de vi
/ vim
que você já usou; por exemplo,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
O conjunto externo de parênteses cria um subshell,
então a mudança manual no valor de SHLVL
não contamina o ambiente de shell atual (pai).
É claro que a palavra-chave command
está lá para evitar as funções
de se chamarem (o que resultaria em um loop de recursão infinito).
E é claro que você deve colocar essas definições
no seu .bashrc
ou outro arquivo de inicialização.
Existe uma ligeira ineficiência no que precede. Em algumas conchas (bash sendo um), se você disser
(cmd1; cmd2; …; cmdn)
onde cmdn
é um programa externo e executável
(ou seja, não é um comando interno), o shell mantém um processo extra por aí,
apenas para esperar que cmdn
termine.
Isso é (sem dúvida) desnecessário;
as vantagens e desvantagens são discutíveis.
Se você não se importar de ocupar um pouco de memória e um espaço de processo
(e para ver mais um processo de shell do que você precisa quando faz um ps
),
então faça o acima e pule para a próxima seção.
Ditto se você estiver usando uma casca que não mantém o processo extra por aí.
Mas, se você quiser evitar o processo extra, uma primeira coisa a tentar é
vim() { ( ((SHLVL++)); exec vim "$@");}
O comando exec
está lá para evitar que o processo de shell extra permaneça.
Mas há uma pegadinha.
A manipulação do shell de SHLVL
é um pouco intuitiva:
Quando o shell é iniciado, ele verifica se SHLVL
está definido.
Se não estiver definido (ou definido para algo que não seja um número),
o shell define para 1.
Se estiver definido (para um número), o shell adiciona 1 a ele.
Mas, com essa lógica, se você disser exec sh
, seu SHLVL
deve aumentar.
Mas isso é indesejável, porque seu nível real de shell não aumentou.
O shell lida com isso subtraindo um de SHLVL
quando você faz um 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
Então
vim() { ( ((SHLVL++)); exec vim "$@");}
é uma lavagem; Ele incrementa SHLVL
apenas para decrementar novamente.
Você pode muito bem dizer apenas vim
, sem o benefício de uma função.
Note:
According to Stéphane Chazelas (who knows everything), some shells are smart enough not to do this if theexec
is in a subshell.
Para corrigir isso, você faria
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Então vi que você queria contar vim
levels
independentemente dos níveis de shell.
Bem, o mesmo truque funciona (bem, com uma pequena modificação):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(e assim por diante para vi
, view
, etc.)
O export
é necessário
porque VILVL
não é definido como uma variável de ambiente por padrão.
Mas não precisa fazer parte da função;
você pode apenas dizer export VILVL
como um comando separado (no seu .bashrc
).
E, como discutido acima, se o processo de shell extra não for um problema para você,
você pode fazer command vim
em vez de exec vim
e deixar SHLVL
sozinho:
vim() { ( ((VILVL++)); command vim "$@");}
Personal Preference:
You may want to renameVILVL
to something likeVIM_LEVEL
. When I look at “VILVL
”, my eyes hurt; they can’t tell whether it’s a misspelling of “vinyl” or a malformed Roman numeral.
Se você estiver usando um shell que não suporta SHLVL
(por exemplo, traço),
você pode implementá-lo sozinho, desde que o shell implemente um arquivo de inicialização.
Apenas faça algo como
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
no seu .profile
ou arquivo aplicável.
(Você provavelmente não deve usar o nome SHLVL
, pois isso causará o caos
se você já começou a usar um shell que suporta SHLVL
.)
Outras respostas abordaram o problema de incorporar valores de variáveis de ambiente em seu prompt de shell, então eu não vou repetir isso, especialmente você diz que já sabe como fazer isso.