プログラミング

Bash 現在のインタラクティブシェルが何階層深いかを確認する

https://yuis.xsrv.jp/data/tgqijqUrP36N8FRja4PVKpQJ0WlDhZog.png

先日「Bashインタラクティブシェルを多重起動せずに再起動するには」という記事を書きました。そこでは、exec bashコマンドを使うことで、現在のインタラクティブシェルを新しいものにリフレッシュできるということでしたが、色々いじっているうちに、無視できないディスユーザビリティを発見してしまいました。

そこでexec bashを使用せずに、あまりBashを多重起動しすぎないようにするためにはどうしたらいいかを考えてみました。

カレントのターミナルはttyやptsで表示されますが、これをps fで表すと、ヒエラルキーの表示で何段階bashの階層があるかなどを簡単に確認することができます。

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_96541cc2-e2d8-4b1b-9ca0-f0c5419db068.png

PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND

21929 21930 21930 21929 tty19        0 Sl    1000   0:00 /mnt/c/Program Files/ConEmu/ConEmu/wsl/wslbridge-backend --check-version=0.2.5-dev -363252 -063253 -163254 -k6A72EFE6177C0FE62CC8A91F3E1369AC32E21930 21934 21934 21934 pts/19       0 Ss    1000   0:01  \_ bash -l -i
21934 24318 24318 21934 pts/19       0 S     1000   0:01      \_ bash
24318 25004 25004 21934 pts/19       0 S     1000   0:01          \_ bash
25004 25794 25794 21934 pts/19       0 S     1000   0:01              \_ bash
25794 26603 26603 21934 pts/19       0 R     1000   0:00                  \_ ps fjx

このようにbashが三段多重起動されていることが確認できます。

これを応用して、以下のようなスクリプトを書いてみました。

https://yuis.xsrv.jp/images/ss/ShareX_ScreenShot_7db0e063-69b6-49e8-a362-ff77228b41ad.gif

check-bash-depth(){

    tty="$( tty | sed -Ee 's/\/dev\/(pts|tty)\/(.*)/\2/g' )" ; ps fx -o tty,pid,stat,command,%cpu,%mem --sort=tty | ag "^(pts|tty)/?${tty}\s" | tee

}
yuis ASUS /mnt/c/pg$ check-bash-depth
pts/11    6135 Ss    \_ bash -l -i               0.0  0.0
pts/11    4006 R         \_ ps fx -o tty,pid,st  0.0  0.0
pts/11    4007 S         \_ ag ^(pts|tty)/?11\s  0.0  0.0
pts/11    4009 S         |   \_ sh -c git confi  0.0  0.0
pts/11    4010 R         |       \_ git config   0.0  0.0
pts/11    4008 S         \_ tee                  0.0  0.0

check-bash-depthを実行することで、カレントのターミナルがどれくらいBashインタラクティブシェルの階層を持っているのかがわかるようにしました。これで、カレントのログインシェルをログアウトしない程度に多重起動された中間層のBashをexitし、CPU使用率を抑えつつ作業していくことができます。

表示の通り、カレントのターミナルの全てのプロセスが表示されるわけなので、単にBashの階層を知りたいというだけでなく、カレントのターミナルの全てのインタラクティブシェルの全てのプロセスを確認したい、という場合にも使えます。