現在の shell(以下、current shell) を確認する方法として真っ先に思い浮かぶのは以下だと思います。
$ echo $SHELL /bin/bash
ただ、これは不正解で、$SHELL はあくまでも login shell ですので、
login shell と current shell が違う場合は正しい値を返してくれません。
私の場合ですと、ローカル環境で常時利用しているのは zsh ですが、
login shell は bash です(zsh を login shell にすると重いと教えていただいたことがあるので)。
このようなケースでも正しい値を返す方法が以下です。
$ echo $0 -zsh
shell 上では $0 に current shell が格納されています。
これで解決すれば良いのですが、shellscript 内で確認しようと思うと話しは変わってきます。
shellscript 内で $0 には、script 名が格納されています。
shell 上での利用よりも、shellscript 内での利用頻度の方が高いでしょうからこれでは困ります。
色々調べていたら、現在使っているシェルの名前を知る方法 - 揮発性のメモ を発見しました。
いろいろ参考になりました、ありがとうございます。
readlink /proc/$$/exe
の説明をすると、
Linux の /proc/PID 以下には、プロセスに関する情報が色々入っていて、
- $$ で shellscript 自身の PID を取得して、
- シンボリックリンクの実体のパスを返す readlink に、
- コマンドのパスのシンボリックリンクが含まれている /proc/$$/exe を渡して、
- shellscript を実行している shell を取得する
となります。
これで解決かと思いましたが、以下の欠点があります。
- /proc が Linux にしかない(たぶん)
- 実行した時の shell になるので、current shell とは違う
2点目について説明すると、
shebang に #!/bin/bash と指定してスクリプトを実行したり、
bash /path/to/script のように実行すると、zsh を使っていても /bin/bash が返ってくる、ということです。
今回は、あくまでも current shell を取得したいのでこれでは要件を満たせません。
解決策
実行した shellscript の親プロセスは current shell になっているのではないか、
と当たりをつけて実験したらできました。
1つずつ説明すると、
_PID=$$
で Shellscript 自身の PID を取得して、
_PPID=$(ps -o ppid -p $_PID | awk 'NR==2 { print }')
で、Shellscript 自身の親PID(PPID)を出力しています。
これを更に分解すると、
$ ps -o ppid -p $_PID PPID 12345
のような出力になるので、
awk 'NR==2 { print }'
で 2 行目だけ出力しているようにしています。
--no-headers を使っていない理由は BSD の ps になかったからです。
あとは、親PIDが取れたので、
ps -p $_PPID
で PID 指定で ps しています。
これで 実行した shellscript の親プロセスの情報を取得出来ました。
zsh を使っている状態でこれを実行すると、
$ ./get_current_shell.sh PID TTY TIME CMD 12345 pts/1 00:00:00 zsh
となります。
header を消したければ、同じ要領で awk をかませればよいでしょう。
あとは、grep -qs zsh にマッチすれば zsh、grep -qs bash にマッチすれば bash
といった判定が可能になります。