Kiedy przeczytałem twoje pytanie, moją pierwszą myślą było $SHLVL. Potem zobaczyłem, że chcesz liczyć vimpoziomy
oprócz poziomów powłoki. Prostym sposobem na to jest zdefiniowanie funkcji powłoki:
vim() { ( ((SHLVL++)); command vim "$@");}
To będzie automatycznie i cicho zwiększać za SHLVL
każdym razem, gdy wpiszesz vimpolecenie. Musisz to zrobić dla każdego wariantu vi/ vim, którego kiedykolwiek używałeś; na przykład,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
Zewnętrzny zestaw nawiasów tworzy podpowłokę, więc ręczna zmiana wartości SHLVL
nie zanieczyszcza bieżącego (macierzystego) środowiska powłoki. Oczywiście commandsłowo kluczowe ma zapobiegać wywoływaniu się funkcji (co spowodowałoby nieskończoną pętlę rekurencji). I oczywiście powinieneś umieścić te definicje w swoim .bashrclub innym pliku inicjującym powłokę.
Powyżej jest niewielka nieefektywność. W niektórych muszlach (bash to jeden), jeśli tak mówisz
( cmd 1 ; cmd 2 ; … ; cmd n )
gdzie jest zewnętrzny program wykonywalny (tj. nie wbudowane polecenie), powłoka utrzymuje dodatkowy proces leżący w pobliżu, tylko po to, aby czekać na zakończenie. To (prawdopodobnie) nie jest konieczne; zalety i wady są dyskusyjne. Jeśli nie masz nic przeciwko związaniu odrobiny pamięci i gniazda procesu (i zobaczeniu o jeden proces powłoki więcej niż potrzebujesz, gdy wykonujesz a ), to wykonaj powyższe czynności i przejdź do następnej sekcji. To samo, jeśli używasz powłoki, która nie utrzymuje dodatkowego procesu. Ale jeśli chcesz uniknąć dodatkowego procesu, pierwszą rzeczą do wypróbowania jestcmdncmdnps
vim() { ( ((SHLVL++)); exec vim "$@");}
Jest execto polecenie, aby zapobiec dalszemu procesowi powłoki.
Ale jest gotcha. Obsługa powłoki SHLVLjest nieco intuicyjna: gdy powłoka się uruchamia, sprawdza, czy SHLVLjest ustawiona. Jeśli nie jest ustawiony (lub ustawiony na coś innego niż liczba), powłoka ustawia go na 1. Jeśli jest ustawiony (na liczbę), powłoka dodaje do niego 1.
Ale według tej logiki, jeśli tak mówisz exec sh, SHLVLpowinieneś pójść w górę. Ale to niepożądane, ponieważ twój rzeczywisty poziom pocisków nie wzrósł. Powłoka radzi sobie z tym, odejmując jedną z następujących SHLVL
czynności 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
Więc
vim() { ( ((SHLVL++)); exec vim "$@");}
jest praniem; zwiększa się SHLVLtylko w celu ponownego zmniejszenia. Równie dobrze możesz powiedzieć vim, bez korzystania z funkcji.
Uwaga:
Według Stéphane'a Chazelasa (który wie wszystko) , niektóre powłoki są wystarczająco inteligentne, aby tego nie robić, jeśli execsą w podpowłoce.
Aby to naprawić, zrobiłbyś
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Potem zobaczyłem, że chcesz liczyć vimpoziomy
niezależnie od poziomów powłoki. Cóż, działa dokładnie ta sama sztuczka (z niewielką modyfikacją):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(i tak dalej vi, viewitp) Jak exportto konieczne, ponieważ VILVLnie jest zdefiniowany jako zmiennej środowiskowej domyślnie. Ale to nie musi być częścią funkcji; możesz po prostu wypowiedzieć export VILVLjako osobne polecenie (w swoim .bashrc). Jak wspomniano powyżej, jeśli proces dodatkowej powłoki nie stanowi dla ciebie problemu, możesz command vimzamiast tego zrobić exec vimi zostawić w SHLVLspokoju:
vim() { ( ((VILVL++)); command vim "$@");}
Preferencje osobiste:
możesz chcieć zmienić nazwę VILVLna coś podobnego VIM_LEVEL. Kiedy patrzę na „ VILVL”, bolą mnie oczy; nie potrafią powiedzieć, czy jest to błędna pisownia „winylu”, czy zniekształcona rzymska cyfra.
Jeśli używasz powłoki, która nie obsługuje SHLVL(np. Myślnik), możesz ją zaimplementować samodzielnie, o ile powłoka implementuje plik startowy. Po prostu zrób coś takiego
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
w twoim .profilelub odpowiednim pliku. (Prawdopodobnie nie powinieneś używać nazwy SHLVL, ponieważ spowoduje to chaos, jeśli zaczniesz używać powłoki, która obsługuje SHLVL).
Inne odpowiedzi dotyczyły problemu osadzania wartości zmiennych środowiskowych w zachęcie powłoki, więc nie powtórzę tego, zwłaszcza, że mówisz, że już wiesz, jak to zrobić.
$SHLVLzmienna (obsługiwana przez kilka powłok) jest tym, czego szukasz?