Quando li sua pergunta, meu primeiro pensamento foi $SHLVL
. Então vi que você queria contar vim
níveis
além dos níveis de shell. Uma maneira simples de fazer isso é definir uma função shell:
vim() { ( ((SHLVL++)); command vim "$@");}
Isso aumentará automaticamente e silenciosamente SHLVL
toda vez que você digitar um vim
comando. Você precisará fazer isso para cada variante de vi
/ vim
que você usar; por exemplo,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
O conjunto externo de parênteses cria um subshell, portanto, a alteração manual no valor de SHLVL
não contamina o ambiente atual do shell (pai). Obviamente, a command
palavra-chave existe para impedir que as funções se chamem (o que resultaria em um loop infinito de recursão). E é claro que você deve colocar essas definições no seu .bashrc
ou em outro arquivo de inicialização do shell.
Há uma ligeira ineficiência no exposto acima. Em algumas conchas (bash sendo uma), se você disser
( cmd 1 ; cmd 2 ; … ; cmd n )
Onde é um programa executável externo (ou seja, não um comando interno), o shell mantém um processo extra por aí, apenas para aguardar o término. Isso é (sem dúvida) desnecessário; as vantagens e desvantagens são discutíveis. Se você não se importa em amarrar um pouco de memória e um slot de processo (e ver mais um processo de shell do que o necessário quando faz um ), faça o acima e pule para a próxima seção. O mesmo se você estiver usando um shell que não mantém o processo extra por aí. Mas, se você quiser evitar o processo extra, a primeira coisa a tentar écmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
O exec
comando existe para impedir que o processo de shell extra permaneça.
Mas, há uma pegadinha. O manuseio do shell SHLVL
é um tanto intuitivo: quando o shell inicia, ele verifica se SHLVL
está definido. Se não estiver definido (ou definido como algo diferente de um número), o shell o definirá como 1. Se estiver definido (como um número), o shell adicionará 1 a ele.
Mas, por essa lógica, se você diz exec sh
, você SHLVL
deve subir. Mas isso é indesejável, porque o 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
assim
vim() { ( ((SHLVL++)); exec vim "$@");}
é uma lavagem; ele é incrementado SHLVL
apenas para diminuí-lo novamente. Você pode apenas dizer vim
, sem o benefício de uma função.
Nota:
De acordo com Stéphane Chazelas (quem sabe tudo) , algumas conchas são inteligentes o suficiente para não fazer isso se exec
estiverem em um subshell.
Para consertar isso, você faria
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Então vi que você queria contar vim
níveis
independentemente dos níveis do shell. Bem, exatamente 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.) A export
é necessária 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 extra de shell não for um problema para você, você pode fazer em command vim
vez de exec vim
e deixar em SHLVL
paz:
vim() { ( ((VILVL++)); command vim "$@");}
Preferência pessoal:
convém renomear VILVL
para algo assim VIM_LEVEL
. Quando olho para " VILVL
", meus olhos doem; eles não sabem dizer se é um erro de ortografia de "vinil" ou um número romano malformado.
Se você estiver usando um shell que não suporta SHLVL
(por exemplo, traço), poderá implementá-lo você mesmo, desde que o shell implemente um arquivo de inicialização. Basta fazer algo como
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
no seu .profile
arquivo ou aplicável. (Você provavelmente não deve usar o nome SHLVL
, pois isso causará caos se você começar a usar um shell compatível SHLVL
.)
Outras respostas abordaram a questão de incorporar valores da variável de ambiente no prompt do shell, então não vou repetir isso, especialmente você diz que já sabe como fazê-lo.
$SHLVL
variável (mantida por várias conchas) é o que você está procurando?