我怎么知道我是否正在运行嵌套shell?

时间:2010-12-22 16:39:56

标签: linux bash shell unix

当使用* nix shell(通常是bash)时,我经常会生成一个子shell,我可以用它处理一个小任务(通常在另一个目录中),然后退出以恢复父shell的会话

有一段时间,我会忘记我是在运行嵌套shell,还是在我的顶级shell中,我会不小心产生一个额外的子shell或退出顶层贝壳是错误的。

有没有一种简单的方法可以确定我是否在嵌套的shell中运行?或者我是以完全错误的方式解决我的问题(通过产生子壳)?

8 个答案:

答案 0 :(得分:65)

$SHLVL变量跟踪您的shell嵌套级别:

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

作为产生子shell的替代方法,您可以从堆栈中推送和弹出目录并保持在同一个shell中:

[root@localhost /old/dir]# pushd /new/dir
/new/dir /old/dir
[root@localhost /new/dir]# popd
/old/dir
[root@localhost /old/dir]#

答案 1 :(得分:22)

以下是我的部分提示的简化版本:

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

如果我不在嵌套的shell中,它不会添加任何额外的东西,但如果我处于任何嵌套级别,它会显示深度。

答案 2 :(得分:10)

查看$0:如果它以减号-开头,则您在登录shell中。

答案 3 :(得分:8)

pstree -s $$对于了解您的深度非常有用。

答案 4 :(得分:1)

环境变量$SHLVL包含shell“depth”。

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 \$ '

| tail +2可以从grep输出中删除一行。由于我们在“$(...)”命令替换中使用管道,因此shell需要调用子shell,因此pstree会报告它,而grep会再检测一个sh-级别。

在基于debian的发行版中,pstree是包psmisc的一部分。默认情况下,它可能不会安装在非桌面发行版上。

答案 5 :(得分:0)

ptree $$还会显示您有多少级别

答案 6 :(得分:0)

@John Kugelman says一样,echo $SHLVL会告诉您bash外壳的深度。
作为@Dennis Williamson shows,您可以通过PS1变量编辑提示,以使其打印此值。

我更喜欢它总是显示外壳深度值,所以这是我要做的事情:编辑“〜/ .bashrc”文件:

gedit ~/.bashrc

并将以下行添加到末尾:

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

现在,您将始终在提示上方看到当前bash级别的打印输出。例如:在这里您可以看到我的重击级别(深度)为2,如$SHLVL:2所示:

  

$ SHLVL:2
  7510加布里埃尔〜$

现在,当我通过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还在!

通过在“〜/ .bashrc”文件中使用以下内容,使您的提示还向您显示您正在使用的 git分支

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()最初来自哪里,但是我是于2018年4月5日从Jason McMullan那里得到的。然后我在上周添加了上面显示的$SHLVL部分。

>

示例输出:

  

$ SHLVL:2个母版
  7510-gabriels〜/ GS / dev / temp $

这是一张截图,显示了它的所有荣耀。注意git分支名称master突出显示为白色

enter image description here

交叉引用:

答案 7 :(得分:-1)

如果在子shell中运行,则代码将产生2:

ps | fgrep bash | wc -l

否则,它将产生1。

编辑好吧,这并不像评论中指出的那样强大 另一件要尝试的是

ps -ef | awk '{print $2, " ", $8;}' | fgrep $PPID 
如果你在子shell中,

将产生'bash'。