コマンドを使用できますpstree(Ubuntuにはデフォルトで付属しています)。次に例を示します。現在、WSLで開いているターミナルウィンドウは1つだけです。
User@Wsl:~$ pstree
init─┬─init───bash───pstree
└─{init}
User@Wsl:~$ bash
User@Wsl:~$ sh
$ bash
User@Wsl:~$ pstree
init─┬─init───bash───bash───sh───bash───pstree
└─{init}
実際のLinux / Ubuntu環境では、プロセスツリーはより複雑になります。-s選択したプロセスの親を表示するオプションでツリーをフィルタリングできます。したがって、コマンドは次のようになりますpstree -s $$。ここで$$、現在のPIDを含む環境変数です。
User@Ubuntu:~$ pstree -s $$
systemd──lightdm──lightdm──upstart──gnome-terminal-──bash──pstree
User@Ubuntu:~$ bash
User@Ubuntu:~$ sh
$ bash
User@Ubuntu:~$ pstree -s $$
systemd──lightdm──lightdm──upstart──gnome-terminal-──bash──bash──sh──bash──pstree
参照:
シェルのプロンプトにインジケーターを追加します: @waltinatorのアイデアに基づいて、レベルが1よりも深いときに複数の異なるシェルのプロンプトの前にカウンターを置くために、デモの下に示す行を追加しました。関連する実行コマンド(~/.*rc)ファイルの下部。
gnome-terminal、tty、およびsshセッション内で、WSL、Ubuntu 16.04、Ubuntu 18.04(サーバー/デスクトップ)、Ubuntu 19.04でテストを行いました。これがどのように機能するかを次に示します。

制限は次のとおりです。OSに応じて、カウンターは13〜14レベルの深さでのみ機能します。私は理由を調査するつもりはありません:)
bash> .bashrc:
DEPTH=$(($(pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>') - 1))
if (( DEPTH > 1 )); then PS1=$DEPTH:$PS1; fi
cshおよびtcsh> .cshrc:
@ DEPTH = `pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>'` - 0
if ( $DEPTH > 1 ) then; set prompt="$DEPTH":"$prompt"; endif
zsh> .zshrc:
DEPTH=$(($(pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>') - 1))
if (( DEPTH > 1 )); then PROMPT=$DEPTH:$PROMPT; fi
ksh> .kshrc:
DEPTH=$(($(pstree -s $$ | sed -r 's/\-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>') - 0))
if (( DEPTH > 1 )); then PS1="$DEPTH":"$PS1"'$ '; fi
shそれは実際dashにはUbuntu上にあります-ここでは少し複雑で有線です(詳細については以下のリファレンスをお読みください):
~/.profileファイルを編集し、下部に次の行を追加します。
ENV=$HOME/.shrc; export ENV
ファイルを作成し~/.shrc、ノートは以下の内容ををkshも読み込み$ENV:
#!/bin/dash
DEPTH=$(pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>')
if [ "$0" != 'ksh' ]; then DEPTH=$((DEPTH - 1)); fi
if [ "$DEPTH" -gt 1 ]; then export PS1='$DEPTH:\$ '; fi
参照:
深度を出力するコマンドを作成します。別のオプションは、深度を出力するシェルコマンドを作成することです。この目的のために、実行可能ファイルを作成します(したがって、システム全体でアクセスできる必要があります)。/usr/local/bin/depth
sudo touch /usr/local/bin/depth
sudo chmod +x /usr/local/bin/depth
お気に入りのエディターでファイルを編集し、そのコンテンツとして次の行を追加します。
#!/bin/bash
SHELLS='(bash|zsh|sh|dash|ksh|csh|tcsh)'
DEPTH=$(pstree -s $$ | sed -r 's/-+/\n/g' | grep -Ec "\<$SHELLS\>")
if [[ $@ =~ -v ]]
then
pstree -s $$ | sed -r 's/-+/\n/g' | grep -E "\<$SHELLS\>" | cat -n
fi
echo "DEPTH: $DEPTH"
[[ $DEPTH -gt 1 ]] && exit 0 || exit 1
上記のスクリプトには2つのオプションがあります。-vまたは--verbose、関連するシェルのリストを出力します。そして、深さが1よりも大きいかどうかを確認し、これに基づいて戻るexit 0かexit 1、この方法で使用できる別のオプションdepth && exit。以下に使用例をいくつか示します。
User@Ubuntu:~$ depth # we are at the 1st level - bash
DEPTH: 1
User@Ubuntu:~$ sh
$ csh # we are at the 2nd level - dash
Ubuntu:~% depth # we are at the 3rd level - csh
DEPTH: 3
Ubuntu:~% ksh
$ depth -v # we are at the 4th level - ksh
1 bash
2 sh
3 csh
4 ksh
DEPTH: 4
$ depth && exit # exit to the 3rd level - csh
DEPTH: 4
Ubuntu:~% depth && exit # exit to the 2nd level - dash
DEPTH: 3
exit
$ depth && exit # exit to the 1st level - bash
DEPTH: 2
User@Ubuntu:~$ depth && exit # stay at the 1st level - bash
DEPTH: 1
User@Ubuntu:~$ depth && exit # stay at the 1st level - bash
DEPTH: 1
他のソリューションによる比較:ここで提供されているアプローチの弱点を見つけるために、さらに時間を費やしました。次の2つのケースを想像できました(構文の強調表示を改善するには大文字が必要です)。
suまたはsudo -i関連する場合:
User@Ubuntu:~$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh|su|sudo)\>'
1
User@Ubuntu:~$ echo $SHLVL
1
User@Ubuntu:~$ depth
DEPTH: 1
User@Ubuntu:~$ su spas
Password:
Spas@Ubuntu:~$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh|su|sudo)\>'
1
Spas@Ubuntu:~$ echo $SHLVL
2
Spas@Ubuntu:~$ depth
DEPTH: 2
Spas@Ubuntu:~$ sudo -i
[sudo] password for spas:
Root@Ubuntu:~# ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh|su|sudo)\>'
3
Root@Ubuntu:~# echo $SHLVL
1
Root@Ubuntu:~# depth
DEPTH: 3
バックグラウンドプロセスが起動されると:
User@Ubuntu:~$ bash
User@Ubuntu:~$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>'
2
User@Ubuntu:~$ echo $SHLVL
2
User@Ubuntu:~$ depth
DEPTH: 2
User@Ubuntu:~$ while true; do sleep 10; done &
[1] 10886
User@Ubuntu:~$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>'
3
User@Ubuntu:~$ echo $SHLVL
2
User@Ubuntu:~$ depth
DEPTH: 2
# Note: $SHLVL is not supported only by sh/dash.
# It works with all other tested shells: bash, zsh, csh, tcsh, ksh
User@Ubuntu:~$ sh
$ ps | grep -Ec '\<(bash|zsh|sh|dash|ksh|csh|tcsh)\>'
4
$ echo $SHLVL
2
$ depth
DEPTH: 3