Linuxで現在のシェルを確認する方法とその応用の実務上の結論は「現在processはps -p $$と/proc/$$/exe、機能判定はBASH_VERSION等で確認します。$SHELLの値だけで現在shellを断定しません。」です。環境変数SHELLはlogin shellの候補で、今このcommandを解釈するprocessの証明ではありません。PID、executable、version変数、parent processを別観測として束ねます。
login shellと現在processを分ける
$SHELLは通常accountに設定されたlogin shellを示し、今このcommandを解釈しているprocessと一致しない場合があります。bashからshを起動した場合、terminal multiplexer、container、IDE、cron、sudo経由でも関係が変わります。現在process、parent process、実行mode、scriptのshebangを分けて確認することが重要です。
対話sessionではps -p $$ -o pid=,ppid=,comm=,args=で現在shell候補を見て、readlink /proc/$$/exeが使えるLinuxなら実行fileを確認します。BASH_VERSIONやZSH_VERSIONは該当shell固有の変数です。$0は起動方法やscriptで意味が変わり、先頭dashを付けたlogin shell表現もあるため、単独の断定材料にしません。
SHELL変数と現在PIDの実体を別々に採る
- interactive shellかscriptかを確認する
- process ID $$とparent processを記録する
- Linux /procが利用可能か確認する
- 必要なshell機能をversionとoptionで確認する
調査commandを別shellから起動すると対象そのものが変わるため、元session内で$$を採ります。containerやrestricted procfsで/exeが読めない場合は停止せずunknownを返し、SHELLだけでbash確定にはしません。
ps・procfs・BASH_VERSIONでshellを特定する
現在process名を表示
ps -p $$ -o pid=,ppid=,comm=,args=
commとargsは表示差やwrapperを考慮して読みます。
実行fileへのlinkを確認
readlink -- /proc/$$/exe
Linux /procがmountされ、access可能な場合の補助確認です。
Bashか機能判定
if [ -n "$BASH_VERSION" ]; then printf 'bash=%s\n' "$BASH_VERSION"; else printf '%s\n' 'not detected as Bash'; fi
syntaxを実行する前に対応shellのvariableを確認します。
login shell設定を表示
printf 'SHELL=%s\n' "$SHELL"
現在processではなくaccount設定由来の参考値として扱います。
親processも表示
ps -p $$ -o ppid= | xargs -r ps -o pid=,ppid=,comm=,args= -p
terminal、SSH、wrapper、schedulerの起動経路を補助的に確認します。
subshell・terminal・scriptの実体確認
$$は現在shell processのPIDを示しますが、subshell最適化やwrapperで観察方法に差があります。$SHELLは通常accountのpreferred/login shellです。scriptではshebang、呼び出し方、env解決、container環境も実際のinterpreterを決めます。process名だけでfeature supportを断定せずversionも見ます。
commは短いprocess名、argsは起動引数を含み、wrapperやbusyboxでは表示が期待と異なる場合があります。/procのexe linkは権限、namespace、終了済みprocessの影響を受けます。command -vはPATH上の解決先であり、現在実行中binaryと同じとは限りません。結果にはPID、PPID、tty、実体path、versionを一組で残します。
$$がsubshellで親の値を保つshell、最適化で新processを作らない構文、containerのPID namespace、restricted /proc、remote commandの非対話shellを考慮します。psに結果がない場合をbash以外と決めつけず、process終了や権限errorを確認します。環境変数は継承・上書きできるため、偽装可能な文字列だけでsecurity判断をしません。
subshell・container・消えたproc entryを分ける
- echo $SHELLを現在shellの証明にする
- process名だけでversionやoptionを決める
- scriptのshebangと呼び出しcommandの差を無視する
- /procが全Unixで使えると思う
- ps argsにsecretが出る点を見落とす
短命subshellではpsと/procの取得間にPIDが消えることがあります。空値をshへ補完せず、procfs非mount、permission、raceを別statusにし、同じsessionでPID・comm・versionを一括再取得します。
login設定を書き換えずprocess lineageを読む
確認のためにdefault shellや/etc/passwdを変更しません。process argsにはsecretが含まれる可能性があるため、ps出力を共有前にreviewします。未知のshellでBash固有syntaxを試してerrorを抑え込まず、portableな読み取りから始めます。
確認目的でchsh、/etc/passwd、profile、default shell linkを変更しません。production userのlogin shell変更はjob、SFTP、service account、automationへ影響するため別の承認手順です。調査commandのargsにtokenを含めるとps出力へ露出するので、機密引数を持つprocessを広く収集・共有しないよう権限と保存先を制限します。
shell判定を移植可能にする
login shell、Bashからsh、subshell、script直接実行、sh script、SSH non-interactive、cron相当で各値を比較します。PID、PPID、exe、version、$SHELLを一組にして違いを記録します。
bash、sh、可能ならzsh等で対話session、明示的subshell、script、ssh remote command、sudoをsample化します。各ケースで$SHELL、$0、$$、ps、/proc、固有version変数、shebangを表にし、どの列が『login設定』『current interpreter』『script指定』を示すか確認します。期待と異なる場合は起動chainをparent PIDから追います。
PID・exe・versionを一つのshell recordにする
scriptは特定shellの構文を使うなら明示的shebangと最低versionを定め、実行冒頭で必要featureを検査します。$SHELLで分岐してsyntaxを変えるより、POSIX準拠範囲を選ぶか、必要interpreterを直接起動します。CIではcommand -v、version、shell optionsを記録し、aliasやinteractive profileに依存しない環境でtestします。
判定結果からPOSIX構文かBash構文を選ぶ
ユーザー設定を知るならgetent passwd等のaccount情報、現在の対話processならpsと/proc、scriptの解釈系ならshebangと実行方法を使います。『現在のshell』という質問を三つへ分ければ、$SHELLだけの誤答を避けられます。互換性問題の調査ではshell名に加え、versionと有効optionまで確認してから修正を選びます。
合格はbash、dash、subshell、procfs制限のfixtureでlogin候補とcurrent executableを混同しないことです。証拠が食い違うrunはunknownとして保留し、POSIX構文だけで再実行します。

コメント