Коли я читав ваше запитання, моя перша думка була $SHLVL
. Потім я побачив, що ви хочете порахувати vim
рівні,
крім рівнів оболонки. Простий спосіб зробити це - визначити функцію оболонки:
vim() { ( ((SHLVL++)); command vim "$@");}
Це автоматично та беззвучно збільшуватиметься SHLVL
кожного разу при введенні vim
команди. Вам потрібно буде зробити це для кожного варіанту vi
/, vim
який ви коли-небудь використовуєте; наприклад,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
Зовнішній набір дужок створює додаткову оболонку, тому ручна зміна значення SHLVL
не забруднює поточне середовище (батьківське) оболонки. Звичайно, command
ключове слово є для запобігання виклику функцій (що призведе до нескінченного циклу рекурсії). І звичайно, ви повинні помістити ці визначення у свій .bashrc
чи інший файл ініціалізації оболонки.
Тут є невелика неефективність. У деяких снарядах, якщо ви скажете
( cmd 1 ; cmd 2 ; … ; cmd n )
де є зовнішня, виконувана програма (тобто не вбудована команда), оболонка зберігає додатковий процес, що лежить навколо, лише для того, щоб дочекатися його завершення. Це (певно) не обов’язково; переваги та недоліки дискусійні. Якщо ви не проти зав'язати трохи пам’яті та слот для процесу (і побачити ще один процес оболонки, ніж вам потрібно, коли ви робите ), виконайте вищесказане та перейдіть до наступного розділу. Дітто, якщо ви використовуєте оболонку, яка не підтримує зайвий процес навколо. Але, якщо ви хочете уникнути зайвого процесу, спершу потрібно спробуватиcmdn
cmdn
ps
vim() { ( ((SHLVL++)); exec vim "$@");}
exec
Команда там , щоб запобігти додатковий процес оболонки від затяжною.
Але, є єва. Обробка оболонки SHLVL
дещо інтуїтивно зрозуміла: коли оболонка запускається, вона перевіряє, чи SHLVL
встановлено. Якщо його не встановлено (або встановлено щось інше, ніж число), оболонка встановлює його на 1. Якщо він встановлений (до числа), оболонка додає до нього 1.
Але, за цією логікою, якщо ви скажете exec sh
, ви SHLVL
повинні піти вгору. Але це небажано, оскільки ваш реальний рівень оболонки не збільшився. Оболонка обробляє це шляхом вирахування одного з SHLVL
коли ви робите 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
Тому
vim() { ( ((SHLVL++)); exec vim "$@");}
є миття; він збільшується SHLVL
лише для того, щоб знову його зменшити. Ви можете просто сказати vim
, без користі функції.
Примітка:
За словами Стефана Шазеласа (який знає все) , деякі снаряди досить розумні, щоб цього не робити, якщо він exec
знаходиться в нижній частині корпусу .
Щоб виправити це, ви зробили б
vim() { ( ((SHLVL+=2)); exec vim "$@");}
Потім я побачив, що ви хочете рахувати vim
рівні
незалежно від рівнів оболонки. Ну, точно такий же трюк працює (ну, з незначною модифікацією):
vim() { ( ((SHLVL++, VILVL++)); export VILVL; exec vim "$@");}
(І так далі для vi
, view
і т.д.), export
необхідно тому , що VILVL
не визначений в якості змінної середовища за замовчуванням. Але це не повинно бути частиною функції; ви можете просто сказати export VILVL
як окрему команду (у своєму .bashrc
). І, як було сказано вище, якщо процес додаткової оболонки не є проблемою для вас, ви можете зробити це command vim
замість цього exec vim
і залишити в SHLVL
спокої:
vim() { ( ((VILVL++)); command vim "$@");}
Особисті переваги:
Ви можете перейменувати VILVL
щось на зразок VIM_LEVEL
. Коли я дивлюсь на " VILVL
", мені болять очі; вони не можуть сказати, чи це неправильне написання "вінілу" чи неправильна римська цифра.
Якщо ви використовуєте оболонку, яка не підтримує SHLVL
(наприклад, тире), ви можете реалізувати її самостійно до тих пір, поки оболонка реалізує файл запуску. Просто роби щось подібне
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
у вашому .profile
або застосовному файлі. (Напевно, ви не повинні використовувати ім'я SHLVL
, оскільки це спричинить хаос, якщо ви коли-небудь почнете використовувати оболонку, яка підтримує SHLVL
.)
Інші відповіді стосувалися питання вбудовування значень змінних середовищ у ваш запит на оболонку, тому я не повторюю це, особливо ви кажете, що вже знаєте, як це зробити.
$SHLVL
потрібна змінна (підтримується кількома оболонками)?