Nextrp [CPP] RU + Many GEOs Игра на карте России | NEXTRP

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

linux bash shell unix

11108 просмотра

8 ответа

12928 Репутация автора

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.

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.

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?

Автор: Mansoor Siddiqui Источник Размещён: 22.12.2010 04:39

Ответы (8)


-1 плюса

10433 Репутация автора

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

ps | fgrep bash | wc -l

Otherwise, it will yield 1.

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

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

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

Автор: Victor Sorokin Размещён: 22.12.2010 04:43

11 плюса

67506 Репутация автора

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

Автор: martin clayton Размещён: 22.12.2010 04:47

69 плюса

259939 Репутация автора

Решение

The $SHLVL variable tracks your shell nesting level:

$ 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]#
Автор: John Kugelman Размещён: 22.12.2010 04:48

23 плюса

257428 Репутация автора

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.

Автор: Dennis Williamson Размещён: 22.12.2010 07:27

0 плюса

177815 Репутация автора

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

Автор: glenn jackman Размещён: 22.12.2010 07:32

8 плюса

154 Репутация автора

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

Автор: melchi Размещён: 31.01.2014 07:10

1 плюс

626 Репутация автора

The environment variable $SHLVL contains the shell "depth".

echo $SHLVL

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

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 sudo or became unreliable with env -i.

None of them can correctly deal with 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 +2 is there to remove one line from the grep output. 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.


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

Автор: loxaxs Размещён: 02.11.2017 04:49

0 плюса

3161 Репутация автора

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

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

gedit ~/.bashrc

and add the following line to the end:

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

Now you will always see 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:

$SHLVL:2
7510-gabriels ~ $

Now, watch the prompt as I go down into some bash levels via the bash command, 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:

$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 ~ $ 
Автор: Gabriel Staples Размещён: 26.08.2019 11:12
Вопросы из категории :
32x32