当使用* nix shell(通常是bash)时,我经常会生成一个子shell,我可以用它处理一个小任务(通常在另一个目录中),然后退出以恢复父shell的会话
有一段时间,我会忘记我是在运行嵌套shell,还是在我的顶级shell中,我会不小心产生一个额外的子shell或退出顶层贝壳是错误的。
有没有一种简单的方法可以确定我是否在嵌套的shell中运行?或者我是以完全错误的方式解决我的问题(通过产生子壳)?
答案 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
,突出显示为白色!
答案 7 :(得分:-1)
如果在子shell中运行,则代码将产生2:
ps | fgrep bash | wc -l
否则,它将产生1。
编辑好吧,这并不像评论中指出的那样强大 另一件要尝试的是
ps -ef | awk '{print $2, " ", $8;}' | fgrep $PPID
如果你在子shell中,将产生'bash'。