pstree
기본적으로 Ubuntu와 함께 제공되는 명령을 사용할 수 있습니다 . 다음은 예입니다-현재 WSL에 열린 터미널 창이 하나뿐입니다.
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 's idea 에 따라 레벨이 1보다 깊을 때 여러 쉘에 대한 프롬프트 앞에 카운터를 갖기 위해 데모 아래에 선을 추가했습니다. 관련 실행 명령 ( ~/.*rc
) 파일 의 맨 아래에 있습니다.
그놈 터미널, 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
우분투에 있습니다. 여기 상황이 약간 복잡하고 연결되어 있습니다 (자세한 내용은 아래 참조를 읽으십시오).
~/.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
위의 스크립트에는 두 가지 옵션이 -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
다른 솔루션과의 비교 : 여기에 제공된 접근 방식의 약점을 찾기 위해 추가 시간을 보냈습니다. 나는 다음 두 가지 경우를 상상할 수 있었다 (구문 강조를 더 잘하기 위해서는 대문자가 필요하다) :
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