Подтвердить что ты не робот

Как узнать, работает ли я вложенная оболочка?

При использовании оболочки * nix (обычно bash) я часто создаю суб-оболочку, с которой я могу позаботиться о небольшой задаче (обычно в другом каталоге), а затем выйти из нее, чтобы возобновить сеанс родительская оболочка.

Время от времени я потеряю информацию о том, запускаю ли я вложенную оболочку или в оболочку верхнего уровня, и я случайно создаю дополнительную суб-оболочку или выйду из верхнего уровня по ошибке.

Есть ли простой способ определить, запущен ли я во вложенной оболочке? Или я перехожу к своей проблеме (путем нереста суб-оболочек) совершенно неправильно?

4b9b3361

Ответ 1

Переменная $SHLVL отслеживает уровень вложенности оболочки:

$ echo $SHLVL
1
$ bash
$ echo $SHLVL
2
$ exit
$ echo $SHLVL
1

В качестве альтернативы нерестам суб-оболочек вы можете нажимать и вызывать каталоги из стека и оставаться в одной оболочке:

[[email protected] /old/dir]# pushd /new/dir
/new/dir /old/dir
[[email protected] /new/dir]# popd
/old/dir
[[email protected] /old/dir]#

Ответ 2

Вот упрощенная версия части моего приглашения:

PS1='$(((SHLVL>1))&&echo $SHLVL)\$ '

Если я не во вложенной оболочке, это не добавляет ничего лишнего, но показывает глубину, если я нахожусь на любом уровне вложенности.

Ответ 3

Посмотрите $0: если он начинается с минуса -, вы находитесь в оболочке входа.

Ответ 4

pstree -s $$ весьма полезно видеть вашу глубину.

Ответ 5

Переменная среды $SHLVL содержит "глубину" оболочки.

echo $SHLVL

Глубина оболочки также может быть определена с помощью pstree (версия 23 и выше):

pstree -s $$ | grep sh- -o | wc -l

Я нашел второй способ быть более надежным, чем первый, значение которого было reset при использовании sudo или стало ненадежным с env -i.

Ни один из них не может корректно иметь дело с su.


Информация может быть доступна в вашем приглашении:

PS1='\[email protected]\h/${SHLVL} \w \$ '
PS1='\[email protected]\h/$(pstree -s $$ | grep sh- -o | tail +2 | wc -l) \w \$ '

| tail +2 следует удалить одну строку из вывода grep. Поскольку мы используем конвейер внутри подстановки "$(...)", оболочке нужно вызвать под-оболочку, поэтому pstree сообщает об этом, а grep обнаруживает еще один уровень sh-.


В дистрибутивах на основе debian pstree является частью пакета psmisc. Возможно, он не будет установлен по умолчанию для дистрибутивов без рабочего стола.

Ответ 6

ptree $$ также покажет вам, сколько уровней вы

Ответ 7

Я получаю root login.... bash... поэтому для меня нужен 4-й элемент bash, нет grep и т.д. pstree -p $$ | awk '{if ($ 4 ~ "bash" ) {print $0}}' | wc -l работает лучше. Мне нужно -p получить pid, а не pstree на основе строк. Mac OSx 10.11.6 Я мог бы просто распечатать 4 доллара, но полезно видеть целые строки в отладках

Ответ 8

As @Джон Кугельман говорит, echo $SHLVL расскажет вам глубину оболочки bash.
И, как показывает @Dennis Williamson, вы можете отредактировать ваше приглашение через переменную PS1, чтобы оно напечатало это значение.

Я предпочитаю, чтобы он всегда печатал значение глубины оболочки, поэтому вот что я сделал: отредактируйте файл "~/.bashrc":

gedit ~/.bashrc

и добавьте следующую строку в конец:

export PS1='\$SHLVL'":$SHLVL\n$PS1"

Теперь вы всегда будете видеть распечатку вашего текущего уровня bash чуть выше вашего приглашения. Пример: здесь вы можете видеть, что я нахожусь на уровне bash (глубина) 2, как указано $SHLVL:2:

$SHLVL:2
7510-gabriels ~ $

Теперь следите за подсказкой, когда я спускаюсь на некоторые уровни bash с помощью команды bash, а затем возвращаюсь через exit. Здесь вы видите мои команды и подсказку (ответ), начиная с уровня 2 и опускаясь до 5, затем возвращаясь к уровню 2:

$SHLVL:2 
7510-gabriels ~ $ bash
$SHLVL:3 
7510-gabriels ~ $ bash
$SHLVL:4 
7510-gabriels ~ $ bash
$SHLVL:5 
7510-gabriels ~ $ exit
exit
$SHLVL:4 
7510-gabriels ~ $ exit
exit
$SHLVL:3 
7510-gabriels ~ $ exit
exit
$SHLVL:2 
7510-gabriels ~ $ 

Бонус: всегда показывайте в своем терминале ваш текущий git branch, в котором вы тоже находитесь!

В вашем приглашении также отобразится ваша ветка git, над которой вы работаете, вместо этого используйте в файле "~/.bashrc" следующее:

git_show_branch() {
    __gsb_BRANCH=$(git symbolic-ref -q --short HEAD 2>/dev/null)
    if [ -n "$__gsb_BRANCH" ]; then
        echo "$__gsb_BRANCH"
    fi
}
export PS1="\e[7m\$(git_show_branch)\e[m\n\h \w $ "
export PS1='\$SHLVL'":$SHLVL $PS1"

Источник: я понятия не имею, откуда взялся git_show_branch(), но я получил его от Джейсона Макмаллана 5 апреля 2018 года. Затем я добавил часть $SHLVL, показанную выше, только на прошлой неделе.

Пример вывода:

$SHLVL:2 master
7510-gabriels ~/GS/dev/temp $

И вот скриншот, показывающий его во всей красе. Обратите внимание на название ветки git, master, выделенное белым!

enter image description here

Перекрестная ссылка:

Ответ 9

Если вы используете внутри подкоманды следующий код, вы получите 2:

ps | fgrep bash | wc -l

В противном случае это даст 1.

EDIT Хорошо, это не столь надежный подход, как было указано в комментариях:)
Другое дело:

ps -ef | awk '{print $2, " ", $8;}' | fgrep $PPID 

даст 'bash', если вы находитесь в суб-оболочке.