Как узнать, что я запускаю вложенную оболочку?
при использовании оболочки *nix (обычно bash) я часто создаю суб-оболочку, с помощью которой я могу позаботиться о небольшой задаче (обычно в другом каталоге), а затем выйти из нее, чтобы возобновить сеанс родительской оболочки.
время от времени я теряю контроль над тем, запускаю ли я вложенную оболочку или в моей оболочке верхнего уровня, и я случайно создам дополнительную под-оболочку или выйду из оболочки верхнего уровня по ошибке.
есть ли простой способ определить, работаю ли я во вложенной оболочке? Или я собираюсь решить свою проблему (путем нереста под-оболочек) совершенно неправильно?
7 ответов:
The
$SHLVL
переменная отслеживает уровень вложенности оболочки:$ echo $SHLVL 1 $ bash $ echo $SHLVL 2 $ exit $ echo $SHLVL 1
в качестве альтернативы нереста суб-оболочки вы можете нажать и поп каталоги из стека и остаться в той же оболочке:
[root@localhost /old/dir]# pushd /new/dir /new/dir /old/dir [root@localhost /new/dir]# popd /old/dir [root@localhost /old/dir]#
вот упрощенная версия части моей подсказки:
PS1='$(((SHLVL>1))&&echo $SHLVL)$ '
Если я не в подрешетке, он не добавляет ничего лишнего, но он показывает глубину, если я нахожусь на любом уровне подрешетки.
переменной окружения
$SHLVL
содержит оболочку "глубина".echo $SHLVL
глубина раковины также может быть определена с помощью
pstree
(версия 23 и выше):pstree -s $$ | grep sh- -o | wc -l
я нашел второй способ быть более надежным, чем первый, значение которого было сброшено при использовании
sudo
или стал ненадежным сenv -i
.ни один из них не может правильно справиться с
su
.
информацию можно сделать доступной в вашем подсказка:
PS1='\u@\h/${SHLVL} \w $ ' PS1='\u@\h/$(pstree -s $$ | grep sh- -o | tail +2 | wc -l) \w $ '
The
| tail +2
есть ли, чтобы удалить одну строку изgrep
выход. Поскольку мы используем конвейер внутри "$(...)
" подстановка команд, оболочка должна вызывать суб-оболочку, поэтому pstree сообщает об этом, и grep обнаруживает еще один
Если вы работаете внутри суб-оболочки следующий код даст 2:
ps | fgrep bash | wc -l
в противном случае, это даст 1.
EDIT хорошо, это не так надежный подход, как было указано в комментариях:)
Еще одна вещь, чтобы попробовать этоps -ef | awk '{print , " ", ;}' | fgrep $PPID
даст 'Баш', если вы в суб-оболочки.