Когда я прочитал твой вопрос, моя первая мысль была $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 ), то выполните вышеуказанное и перейдите к следующему разделу. То же самое, если вы используете оболочку, которая не мешает дополнительному процессу. Но если вы хотите избежать дополнительного процесса, первое, что нужно попробовать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
(например, dash), вы можете реализовать ее самостоятельно, если оболочка реализует файл запуска. Просто сделай что-то вроде
if [ "$SHELL_LEVEL" = "" ]
then
SHELL_LEVEL=1
else
SHELL_LEVEL=$(expr "$SHELL_LEVEL" + 1)
fi
export SHELL_LEVEL
в вашем .profile
или соответствующем файле. (Вы, вероятно, не должны использовать имя SHLVL
, поскольку это вызовет хаос, если вы когда-нибудь начнете использовать оболочку, которая поддерживает SHLVL
.)
Другие ответы касались вопроса о встраивании значений (переменных) среды в ваше приглашение оболочки, поэтому я не буду повторять это, особенно если вы говорите, что уже знаете, как это сделать.
$SHLVL
переменная (поддерживаемая несколькими оболочками) тем, что вы ищете?