Linux 我怎么知道我是否正在运行一个嵌套的 shell?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4511407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:16:56  来源:igfitidea点击:

How do I know if I'm running a nested shell?

linuxbashshellunix

提问by Mansoor Siddiqui

When using a *nix shell (usually bash), I often spawn a sub-shell with which I can take care of a small task (usually in another directory), then exit out of to resume the session of the parent shell.

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

Once in a while, I'll lose track of whether I'm running a nested shell, or in my top-level shell, and I'll accidentally spawn an additional sub-shell or exit out of the top-level shell by mistake.

有时,我会忘记我是在运行嵌套 shell 还是在我的顶级 shell 中运行,并且我会不小心生成一个额外的子 shell 或错误地退出顶级 shell .

Is there a simple way to determine whether I'm running in a nested shell? Or am I going about my problem (by spawning sub-shells) in a completely wrong way?

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

采纳答案by John Kugelman

The $SHLVLvariable tracks your shell nesting level:

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

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


As an alternative to spawning sub-shells you could push and pop directories from the stack and stay in the same shell:

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

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

回答by Victor Sorokin

If you running inside sub-shell following code will yield 2:

如果您在子 shell 中运行以下代码将产生 2:

ps | fgrep bash | wc -l

Otherwise, it will yield 1.

否则,它将产生 1。

EDITOk, it's not so robust approach as was pointed out in comments :)
Another thing to try is

编辑好的,它不像评论中指出的那样强大:)
另一件要尝试的事情是

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

will yield 'bash' if you in sub-shell.

如果您在子 shell 中,将产生 'bash'。

回答by martin clayton

Look at $0: if it starts with a minus -, you're in the login shell.

看看$0:如果它以减号开头-,则您在登录外壳程序中。

回答by Paused until further notice.

Here is a simplified version of part of my prompt:

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

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

If I'm not in a nested shell, it doesn't add anything extra, but it shows the depth if I'm in any level of nesting.

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

回答by glenn Hymanman

ptree $$will also show you how many levels deep you are

ptree $$还会告诉你你有多深

回答by melchi

pstree -s $$is quite useful to see your depth.

pstree -s $$查看您的深度非常有用。

回答by loxaxs

The environment variable $SHLVLcontains the shell "depth".

环境变量$SHLVL包含外壳“深度”。

echo $SHLVL

The shell depth can also be determined using pstree(version 23 and above):

外壳深度也可以使用pstree(版本 23 及更高版本)确定:

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

I've found the second way to be more robust than the first whose value was reset when using sudoor became unreliable with env -i.

我已经找到了第二种方式比,它的值是复位当使用第一更强大的sudo或不可靠成为与env -i

None of them can correctly deal with su.

他们都不能正确处理su.



The information can be made available in your prompt:

这些信息可以在您的提示中提供:

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

The | tail +2is there to remove one line from the grepoutput. Since we are using a pipeline inside a "$(...)" command substitution, the shell needs to invoke a sub-shell, so pstree report it and grep detects one more sh-level.

| tail +2是存在于从删除一个线路grep输出。由于我们在 " $(...)" 命令替换中使用了管道,所以 shell 需要调用一个子 shell,所以 pstree 报告它并且 grep 检测到另一个sh-级别。



In debian-based distributions, pstreeis part of the package psmisc. It might not be installed by default on non-desktop distributions.

在基于 debian 的发行版中,pstreepsmisc. 默认情况下,它可能不会安装在非桌面发行版上。

回答by Gabriel Staples

As @John Kugelman says, echo $SHLVLwill tell you the bash shell depth.
And as @Dennis Williamson shows, you can edit your prompt via the PS1variable to get it to print this value.

正如@John Kugelman 所说echo $SHLVL会告诉你 bash shell 的深度。
正如@Dennis Williamson 所示,您可以通过PS1变量编辑提示以使其打印此值。

I prefer that it alwaysprints the shell depth value, so here's what I've done: edit your "~/.bashrc" file:

我更喜欢它总是打印外壳深度值,所以这是我所做的:编辑你的“~/.bashrc”文件:

gedit ~/.bashrc

and add the following line to the end:

并将以下行添加到末尾:

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

Now you will alwayssee a printout of your current bash level just above your prompt. Ex: here you can see I am at a bash level (depth) of 2, as indicated by the $SHLVL:2:

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

$SHLVL:2
7510-gabriels ~ $

$SHLVL:2
7510-gabriels ~ $

Now, watch the prompt as I go down into some bash levels via the bashcommand, then come back up via exit. Here you see my commands and prompt (response), starting at level 2 and going down to 5, then coming back up to level 2:

现在,当我通过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 ~ $ 

Bonus: always show in your terminal your current git branchyou are on too!

奖励:始终在您的终端中显示您当前所在的git branch位置!

Make your prompt also show you your git branch you are working onby using the following in your "~/.bashrc" file instead:

通过在“~/.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"

Source: I have no idea where git_show_branch()originally comes from, but I got it from Jason McMullan on 5 Apr. 2018. I then added the $SHLVLpart shown above just last week.

来源:我不知道git_show_branch()最初来自哪里,但我于 2018 年 4 月 5 日从 Jason McMullan 那里得到它。然后我添加了$SHLVL上周显示的部分。

Sample output:

示例输出:

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

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

And here's a screenshot showing it in all its glory. Notice the git branch name, master, highlighted in white!

这是一个屏幕截图,展示了它的所有荣耀。注意git的分支名称,master突出了白色

enter image description here

在此处输入图片说明

Update to the Bonus section

更新奖金部分

I've improved it again and put my ~/.bashrc file on github here. Here's a sample output of the new terminal prompt. Notice how it shows the shell level as 1, and it shows the branch name of the currently-checked-out branch (masterin this case) whenever I'm inside a local git repo!:

我再次改进它并将我的 ~/.bashrc 文件放在 github here 上。这是新终端提示的示例输出。请注意它如何将 shell 级别显示为 1,并且master每当我在本地 git 存储库中时,它都会显示当前签出的分支(在本例中)的分支名称!:

enter image description here

在此处输入图片说明

Cross-referenced:

交叉引用: