Когда я прочитал твой вопрос, моя первая мысль была $SHLVL. Затем я увидел, что вы хотите считать vimуровни
в дополнение к уровням оболочки. Простой способ сделать это - определить функцию оболочки:
vim() { ( ((SHLVL++)); command vim "$@");}
Это будет автоматически и бесшумно увеличиваться при SHLVL
каждом вводе vimкоманды. Вам нужно будет сделать это для каждого варианта vi/, vimкоторый вы когда-либо использовали; например,
vi() { ( ((SHLVL++)); command vi "$@");}
view() { ( ((SHLVL++)); command view "$@");}
Внешний набор скобок создает подоболочку, поэтому ручное изменение значения SHLVL
не загрязняет текущую (родительскую) среду оболочки. Конечно, commandключевое слово используется для предотвращения вызова функций самими собой (что приведет к бесконечному циклу рекурсии). И, конечно, вы должны поместить эти определения в ваш .bashrcили другой файл инициализации оболочки.
В вышесказанном есть небольшая неэффективность. В некоторых оболочках (bash как один), если вы говорите
( cmd 1 ; cmd 2 ; … ; cmd n )
где внешняя исполняемая программа (т. е. не встроенная команда), оболочка удерживает дополнительный процесс, просто ожидая его завершения. Это (возможно) не обязательно; Преимущества и недостатки спорны. Если вы не возражаете связать немного памяти и слот процесса (и увидеть еще один процесс оболочки, чем вам нужно, когда вы делаете a ), то выполните вышеуказанное и перейдите к следующему разделу. То же самое, если вы используете оболочку, которая не мешает дополнительному процессу. Но если вы хотите избежать дополнительного процесса, первое, что нужно попробовать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(например, dash), вы можете реализовать ее самостоятельно, если оболочка реализует файл запуска. Просто сделай что-то вроде
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
в вашем .profileили соответствующем файле. (Вы, вероятно, не должны использовать имя SHLVL, поскольку это вызовет хаос, если вы когда-нибудь начнете использовать оболочку, которая поддерживает SHLVL.)
Другие ответы касались вопроса о встраивании значений (переменных) среды в ваше приглашение оболочки, поэтому я не буду повторять это, особенно если вы говорите, что уже знаете, как это сделать.
$SHLVLпеременная (поддерживаемая несколькими оболочками) тем, что вы ищете?