Coder Perfect

Is it possible to tell if I’m using a nested shell?

Problem

When using a *nix shell (typically bash), I frequently launch a sub-shell with which I may complete a quick job (usually in a different directory), then quit to restart the parent shell’s session.

I occasionally lose track of whether I’m in a nested shell or in my top-level shell, and I’ll unintentionally generate a new sub-shell or exit out of the top-level shell.

Is there a straightforward way to tell if I’m in a nested shell? Is it possible that I’m approaching my problem incorrectly (by spawning sub-shells)?

Asked by Mansoor Siddiqui

Solution #1

The $SHLVL variable keeps track of how deep you’ve nested your shell:

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

Instead of creating sub-shells, you may use the following command to push and pop directories from the stack while staying 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]#

Answered by John Kugelman

Solution #2

Here’s a condensed rendition of a section of my prompt:

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

It doesn’t add anything if I’m not in a nested shell, but it does show the depth if I’m in any level of nesting.

Answered by Dennis Williamson

Solution #3

Look at $0 to see if it begins with a minus -. If it does, you’re in the login shell.

Answered by martin clayton

Solution #4

pstree -s $$ is a great way to see how deep you’ve gone.

Answered by melchi

Solution #5

The shell’s “depth” is stored in the environment variable $SHLVL.

echo $SHLVL

pstree (version 23 and up) can also be used to calculate the shell depth:

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

The second method has shown to be more dependable than the first, which had its value reset when using sudo or became unreliable when using env -i.

None of them know how to deal with su properly.

The following information can be included in your prompt:

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

The | tail +2 specifies that one line should be removed from the grep output. The shell needs to execute a sub-shell because we’re utilizing a pipeline inside a “$(…)” command substitution, thus pstree reports that and grep discovers another sh- level.

Pstree is part of the psmisc package in Debian-based distributions. On non-desktop distributions, it may not be installed by default.

Answered by loxaxs

Post is based on https://stackoverflow.com/questions/4511407/how-do-i-know-if-im-running-a-nested-shell