Коли я читав ваше запитання, моя перша думка була $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 )
де є зовнішня, виконувана програма (тобто не вбудована команда), оболонка зберігає додатковий процес, що лежить навколо, лише для того, щоб дочекатися його завершення. Це (певно) не обов’язково; переваги та недоліки дискусійні. Якщо ви не проти зав'язати трохи пам’яті та слот для процесу (і побачити ще один процес оболонки, ніж вам потрібно, коли ви робите ), виконайте вищесказане та перейдіть до наступного розділу. Дітто, якщо ви використовуєте оболонку, яка не підтримує зайвий процес навколо. Але, якщо ви хочете уникнути зайвого процесу, спершу потрібно спробуватиcmdncmdnps
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потрібна змінна (підтримується кількома оболонками)?