当使用 *nix shell(通常是bash)时,我经常会生成一个子shell,我可以用它来处理一个小任务(通常在另一个目录中),然后退出以恢复父shell的会话。有时候,我会忘记我是在运行一个嵌套的shell,还是在我的顶层shell中运行,我会意外地生成一个额外的子shell,或者错误地退出顶层shell。有没有一种简单的方法来确定我是否在嵌套的shell中运行?或者我是在以一种完全错误的方式处理我的问题(通过生成子shell)?
yws3nbqq1#
$SHLVL变量跟踪您的shell嵌套级别:
$SHLVL
$ 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]#
5cnsuln72#
下面是我的提示部分的简化版本:
PS1='$(((SHLVL>1))&&echo $SHLVL)\$ '
如果我不在嵌套的shell中,它不会添加任何额外的东西,但是如果我在任何嵌套级别中,它会显示深度。
rt4zxlrg3#
看看$0:如果它以--开头,则您处于登录shell中。
$0
-
kpbwa7wx4#
pstree -s $$是非常有用的,可以看到你的深度。
pstree -s $$
dhxwm5r45#
环境变量$SHLVL包含shell“depth”。
echo $SHLVL
shell 深度也可以使用pstree(版本23及以上)确定:
pstree
pstree -s $$ | grep sh- -o | wc -l
我发现第二种方法比第一种方法更健壮,第一种方法的值在使用sudo时被重置,或者在使用env -i时变得不可靠。它们都不能正确处理su。这些信息可以在您的提示中提供:
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包的一部分。默认情况下,它可能不会安装在非桌面发行版上。
| tail +2
grep
$(...)
sh-
psmisc
zysjyyx46#
正如@John Kugelman所说,echo $SHLVL会告诉你bash shell的深度。正如@Dennis威廉姆森所示,您可以通过PS1变量编辑提示符,让它打印这个值。我更喜欢它 * 总是 * 打印shell深度值,所以下面是我所做的:编辑您的~/.bashrc文件:
PS1
~/.bashrc
gedit ~/.bashrc
并在末尾添加以下行:
export PS1='\$SHLVL'":$SHLVL\n$PS1"
现在你将 * 总是 * 在提示符上方看到你当前bash级别的一个标志。例如:这里你可以看到我的bash级别(深度)为2,如$SHLVL:2所示:
$SHLVL:2
$SHLVL:2 7510-gabriels ~ $
现在,当我通过bash命令进入一些bash级别,然后通过exit返回时,请注意提示符。在这里,您可以看到我的命令和提示(响应),从第2级开始,下降到第5级,然后回到第2级:
bash
exit
$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()最初来自哪里,但我在4月5日从Jason McMullan那里得到了它。2018.然后我添加了上周显示的$SHLVL部分。样品输出:
git_show_branch()
$SHLVL:2 master 7510-gabriels ~/GS/dev/temp $
这里有一个屏幕截图显示它在所有的荣耀。注意git分支名称master * 以白色高亮显示 *!
master
我再次改进了PS1提示符,并将其放入eRCaGuy_dotfiles存储库中。它位于我的~/.bash_aliases文件中,该文件来源于我的~/.bashrc文件。在我的~/.bash_aliases文件中搜索我的PS1条目和它们使用的gs_git_show_branch_and_hash函数。下面是新终端提示符的示例输出。注意它是如何将shell级别显示为1的,并且它显示了当前 checkout 的分支的分支名称(在本例中为master),以及它的短git哈希值(在本例中为bac27c7),每当我在本地git repo中时!:
~/.bash_aliases
gs_git_show_branch_and_hash
1
bac27c7
这真的很有帮助,帮助我确保我总是在正确的分支上执行我的git操作,并自动查看我何时将cd放入Git存储库。
git
cd
x8diyxa77#
ptree $$也会显示你有多少层
ptree $$
yvfmudvl8#
如果你在子shell中运行,下面的代码将产生2:
ps | fgrep bash | wc -l
否则,它将产生1。
编辑好吧,这不是那么强大的方法,因为在评论中指出:)
另一个可以尝试的是
ps -ef | awk '{print $2, " ", $8;}' | fgrep $PPID
将产生'bash',如果你在子壳。
8条答案
按热度按时间yws3nbqq1#
$SHLVL
变量跟踪您的shell嵌套级别:作为生成子shell的替代方案,您可以从堆栈中推送和弹出目录并留在同一个shell中:
5cnsuln72#
下面是我的提示部分的简化版本:
如果我不在嵌套的shell中,它不会添加任何额外的东西,但是如果我在任何嵌套级别中,它会显示深度。
rt4zxlrg3#
看看
$0
:如果它以--
开头,则您处于登录shell中。kpbwa7wx4#
pstree -s $$
是非常有用的,可以看到你的深度。dhxwm5r45#
环境变量
$SHLVL
包含shell“depth”。shell 深度也可以使用
pstree
(版本23及以上)确定:我发现第二种方法比第一种方法更健壮,第一种方法的值在使用
sudo
时被重置,或者在使用env -i
时变得不可靠。它们都不能正确处理
su
。这些信息可以在您的提示中提供:
| tail +2
用于从grep
输出中删除一行。由于我们在“$(...)
“命令替换中使用管道,shell需要调用一个子shell,因此pstree报告它,grep检测到另一个sh-
级别。在基于debian的发行版中,
pstree
是psmisc
包的一部分。默认情况下,它可能不会安装在非桌面发行版上。zysjyyx46#
正如@John Kugelman所说,
echo $SHLVL
会告诉你bash shell的深度。正如@Dennis威廉姆森所示,您可以通过
PS1
变量编辑提示符,让它打印这个值。我更喜欢它 * 总是 * 打印shell深度值,所以下面是我所做的:编辑您的
~/.bashrc
文件:并在末尾添加以下行:
现在你将 * 总是 * 在提示符上方看到你当前bash级别的一个标志。例如:这里你可以看到我的bash级别(深度)为2,如
$SHLVL:2
所示:现在,当我通过
bash
命令进入一些bash级别,然后通过exit
返回时,请注意提示符。在这里,您可以看到我的命令和提示(响应),从第2级开始,下降到第5级,然后回到第2级:额外奖励:始终在您的终端中显示您当前的
git branch
!通过在“~/.bashrc”文件中使用以下命令,让提示符也显示您正在使用的git分支:
我不知道
git_show_branch()
最初来自哪里,但我在4月5日从Jason McMullan那里得到了它。2018.然后我添加了上周显示的$SHLVL
部分。样品输出:
这里有一个屏幕截图显示它在所有的荣耀。注意git分支名称
master
* 以白色高亮显示 *!我最新的
PS1
提示我再次改进了
PS1
提示符,并将其放入eRCaGuy_dotfiles存储库中。它位于我的~/.bash_aliases
文件中,该文件来源于我的~/.bashrc
文件。在我的~/.bash_aliases
文件中搜索我的PS1
条目和它们使用的gs_git_show_branch_and_hash
函数。下面是新终端提示符的示例输出。注意它是如何将shell级别显示为
1
的,并且它显示了当前 checkout 的分支的分支名称(在本例中为master
),以及它的短git哈希值(在本例中为bac27c7
),每当我在本地git repo中时!:这真的很有帮助,帮助我确保我总是在正确的分支上执行我的
git
操作,并自动查看我何时将cd
放入Git存储库。对照:
x8diyxa77#
ptree $$
也会显示你有多少层yvfmudvl8#
如果你在子shell中运行,下面的代码将产生2:
否则,它将产生1。
编辑好吧,这不是那么强大的方法,因为在评论中指出:)
另一个可以尝试的是
将产生'bash',如果你在子壳。