Задача : найти, сколько у меня глубоких снарядов.
Детали : я много открываю оболочку от vim. Построить и запустить и выйти. Иногда я забываю и открываю другой vim внутри, а затем еще одну оболочку. :(
Я хочу знать, сколько у меня глубоких снарядов, возможно, даже иметь его на экране оболочки всегда. (Я могу справиться с этой частью).
Мое решение : разобрать дерево процессов, найти vim и bash / zsh и выяснить глубину текущего процесса внутри него.
Что-то подобное уже существует? Я не мог ничего найти.
$SHLVL
переменная (поддерживаемая несколькими оболочками) тем, что вы ищете?fg
вернуться назад, у которого нет этой проблемы.vim
заданий может быть более запутанным, чем наличие стека вложенных процессов. Кстати, я предпочитаю иметь несколько окон , так что я могу легко переходить назад и вперед, но я бы не назвал это проблемой XY только потому, что предпочитаю другой рабочий процесс.Ответы:
Когда я прочитал твой вопрос, моя первая мысль была
$SHLVL
. Затем я увидел, что вы хотите считатьvim
уровни в дополнение к уровням оболочки. Простой способ сделать это - определить функцию оболочки:Это будет автоматически и бесшумно увеличиваться при
SHLVL
каждом вводеvim
команды. Вам нужно будет сделать это для каждого вариантаvi
/,vim
который вы когда-либо использовали; например,Внешний набор скобок создает подоболочку, поэтому ручное изменение значения
SHLVL
не загрязняет текущую (родительскую) среду оболочки. Конечно,command
ключевое слово используется для предотвращения вызова функций самими собой (что приведет к бесконечному циклу рекурсии). И, конечно, вы должны поместить эти определения в ваш.bashrc
или другой файл инициализации оболочки.В вышесказанном есть небольшая неэффективность. В некоторых оболочках (bash как один), если вы говорите
где внешняя исполняемая программа (т. е. не встроенная команда), оболочка удерживает дополнительный процесс, просто ожидая его завершения. Это (возможно) не обязательно; Преимущества и недостатки спорны. Если вы не возражаете связать немного памяти и слот процесса (и увидеть еще один процесс оболочки, чем вам нужно, когда вы делаете a ), то выполните вышеуказанное и перейдите к следующему разделу. То же самое, если вы используете оболочку, которая не мешает дополнительному процессу. Но если вы хотите избежать дополнительного процесса, первое, что нужно попробовать
cmdn
cmdn
ps
Команда
exec
предназначена для предотвращения затягивания процесса дополнительной оболочки.Но есть гоча. Обработка оболочки
SHLVL
несколько интуитивна: при запуске оболочки она проверяет,SHLVL
установлена ли она. Если он не установлен (или не установлен на какое-либо другое значение, кроме числа), оболочка устанавливает его на 1. Если он установлен (на число), оболочка добавляет к нему 1.Но по этой логике, если вы говорите
exec sh
, вашSHLVL
должен идти вверх. Но это нежелательно, потому что ваш реальный уровень оболочки не увеличился. Оболочка обрабатывает это, вычитая один из,SHLVL
когда вы делаетеexec
:Так
это стирка; он увеличивается
SHLVL
только для того, чтобы уменьшить его снова. Вы могли бы просто сказатьvim
, без пользы функции.Чтобы это исправить, вы бы сделали
Затем я увидел, что вы хотите считать
vim
уровни независимо от уровней оболочки. Ну, точно такой же трюк работает (ну, с незначительной модификацией):(и т. д. для
vi
,view
и т. д.)export
Необходим, потому чтоVILVL
не определен как переменная окружения по умолчанию. Но это не обязательно должно быть частью функции; Вы можете просто сказать,export VILVL
как отдельная команда (в вашем.bashrc
). И, как обсуждалось выше, если дополнительный процесс оболочки не является проблемой для вас, вы можете сделатьcommand vim
вместо этогоexec vim
и оставить вSHLVL
покое:Если вы используете оболочку, которая не поддерживает
SHLVL
(например, dash), вы можете реализовать ее самостоятельно, если оболочка реализует файл запуска. Просто сделай что-то вродев вашем
.profile
или соответствующем файле. (Вы, вероятно, не должны использовать имяSHLVL
, поскольку это вызовет хаос, если вы когда-нибудь начнете использовать оболочку, которая поддерживаетSHLVL
.)Другие ответы касались вопроса о встраивании значений (переменных) среды в ваше приглашение оболочки, поэтому я не буду повторять это, особенно если вы говорите, что уже знаете, как это сделать.
источник
ps
илиpstree
, когда вы можете сделать это с помощью встроенных команд оболочки.dash
имеет арифметическое расширение.SHELL_LEVEL=$((SHELL_LEVEL + 1))
должно быть достаточно, даже если $ SHELL_LEVEL был ранее не установлен или пуст. Только если вы должны были переноситься на оболочку Bourne, вам нужно будет прибегнуть к немуexpr
, но тогда вам также придется заменить$(...)
на`..`
.SHELL_LEVEL=`expr "${SHELL_LEVEL:-0}" + 1`
bash
скрипт прочитать ~ / .bashrc с помощью например, создание stdin сокета), тогда это может стать проблемой. Это много «если», но что-то нужно держать в голове (неанизированные данные в арифметическом контексте опасны)Вы можете рассчитывать столько раз, сколько вам нужно, чтобы перейти к дереву процессов, пока не найдете лидера сеанса. Как с
zsh
на Linux:Или POSIXly (но менее эффективно):
Это даст 0 для оболочки, которая была запущена вашим эмулятором терминала или getty, и еще одну для каждого потомка.
Вам нужно сделать это только один раз при запуске. Например с:
в вашем
~/.zshrc
или эквивалентном, чтобы иметь его в вашем приглашении.tcsh
и несколько других оболочек (zsh
,ksh93
,fish
и , поbash
крайней мере) сохранить$SHLVL
переменную, они приращение при запуске (и декремента перед запуском следующей команды сexec
(если этоexec
не в субоболочке , если они не глючит (но многие из них))). Это только отслеживает количество вложений оболочки, но не вложений процессов. Также уровень 0 не гарантирован быть лидером сеанса.источник
Используйте
echo $SHLVL
. Используйте принцип KISS . В зависимости от сложности вашей программы, этого может быть достаточно.источник
bash
, но не дляdash
.Одно из возможных решений - посмотреть на результат
pstree
. При запуске внутри оболочки, которая была порождена изнутриvi
, часть дерева, содержащая списки,pstree
должна показать вам, насколько вы глубоки. Например:источник
Первый вариант - только глубина корпуса.
Простое решение для
bash
: добавьте к.bashrc
следующим двум строкам (или измените текущееPS1
значение):Результат:
Число в начале строки приглашения будет обозначать уровень оболочки.
Второй вариант, с вложенными уровнями vim и shell.
добавить эти строки в
.bashrc
Результат:
v: 1 - уровень глубины vim
s: 3 - уровень глубины оболочки
источник
В вопросе вы упомянули разбор
pstree
. Вот относительно простой способ:В
pstree
опции:-A
- ASCII-вывод для более легкой фильтрации (в нашем случае каждой команде предшествует`-
)-a
- показать также аргументы команды, поскольку в качестве побочного эффекта каждая команда отображается в отдельной строке, и мы можем легко отфильтровать вывод, используяgrep
-l
- не обрезать длинные строки-s
- показать родителей выбранного процесса(к сожалению, не поддерживается в старых версиях
pstree
)$$
- выбранный процесс - PID текущей оболочкиисточник
Это не дает точного ответа на вопрос, но во многих случаях может сделать это ненужным:
Когда вы впервые запустите свою оболочку, запустите
set -o ignoreeof
. Не кладите это в свой~/.bashrc
.Сделайте привычкой вводить Ctrl-D, когда вы думаете, что находитесь в оболочке верхнего уровня и хотите быть уверенным.
Если вы не в оболочке верхнего уровня, Ctrl-D будет сигнализировать «конец ввода» текущей оболочке, и вы вернетесь на один уровень назад.
Если вы находитесь в оболочке верхнего уровня, вы получите сообщение:
Я использую это все время для цепных сессий SSH, чтобы упростить возврат к определенному уровню цепочки SSH. Это работает и для вложенных оболочек.
источник