私の_.profile
_では、次のコードを使用して、ログインシェルが実際にBashである場合にのみBash関連のエイリアスと関数が供給されるようにします:
_# If the current (login) Shell is Bash, then
if [ "${BASH_VERSION:-}" ]; then
# source ~/.bashrc if it exists.
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
_
現在、シェル構成ファイル、スクリプト、関数をバージョン管理下に置いています。私は最近、function funcname()
をfuncname()
に置き換えるなど、Bash固有の機能の恩恵を受けないシェルスクリプトからカジュアルなBashismを削除するプロセスも開始しました。
私のシェルファイルリポジトリでは、Debianの devscriptsからcheckbashisms
ユーティリティを実行するpre-commitフックを構成しましたパッケージ リポジトリ内の各sh
ファイルに、誤ってBash固有の構文を導入しないようにします。ただし、これにより_.profile
_のエラーが発生します。
_possible bashism in .profile line 51 ($BASH_SOMETHING):
if [ "${BASH_VERSION:-}" ]; then
_
checkbashisms
で警告をトリガーしないシェルが実行されていることを確認する方法があるかどうか疑問に思いました。
私は POSIXによってリストされたシェル関連の変数 のリストをチェックし、それらの1つが現在のシェルを表示するために使用できることを期待しました。インタラクティブなダッシュシェルに設定された変数も確認しましたが、やはり適切な候補を見つけることができませんでした。
現時点では、checkbashisms
による処理から_.profile
_を除外しています。小さいファイルなので、手動で確認するのは難しくありません。ただし、問題を調査した後も、実行中のシェルを判断するためのPOSIX準拠の方法があるかどうか(または少なくともcheckbashisms
が失敗しない方法)があるかどうかを知りたいです。
シェル構成ファイルをバージョン管理下に置く理由の1つは、現在定期的にログインしているすべてのシステム(Cygwin、Ubuntu、CentOS(5と7の両方、ユーザーにActive Directoryを使用)で環境を構成することです認証)。私はほとんどの場合、X Windows /デスクトップ環境とSSHを介してリモートホストにログオンします。ただし、これは将来の証拠であり、システムの依存関係や他のツールへの依存度をできるだけ低くしたいと思います。
私は、シェル関連ファイルの構文の単純な自動サニティチェックとしてcheckbashisms
を使用しています。これは完璧なツールではありません。たとえば、スクリプトでの_command -v
_の使用について問題がないように、すでにパッチを適用しています。調査中に、プログラムの実際の目的は、Debianのポリシーに確実に準拠することであり、私が理解しているように、2008年ではなくPOSIX 2004(またはその2013年の改訂)に基づいていることを知りました。
きみの
_# If the current (login) Shell is Bash, then
if [ "${BASH_VERSION:-}" ]; then
# source ~/.bashrc if it exists.
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
_
コードは完全にPOSIXに準拠しており、現在bash
を実行していることを確認する最良の方法です。もちろん、_$BASH_VERSION
_変数はbash固有ですが、それが具体的に使用している理由です。 bash
を実行していることを確認するには!
_$BASH_VERSION
_は、bash
がbash
またはsh
のどちらとして呼び出されても設定されることに注意してください。 bash
を実行していることをアサートしたら、シェルがsh
として呼び出されたことを示すインジケーターとして_[ -o posix ]
_を使用できます(そのオプションは、POSIXLY_CORRECTが環境内にあるか、bash
が_-o posix
_、または環境でSHELLOPTS = posixを使用します。ただし、これらすべてのケースで、bash
はsh
として呼び出されたかのように動作します。
_$BASH_VERSION
_の代わりに使用できる別の変数と、_-x
_オプションが_$BASH
_を渡されない限り、checkbashism
は不満を感じないようです。これはbash
にも固有なので、bash
を実行しているかどうかを判別するためにも使用できるはずです。
また、実際にはcheckbashisms
の適切な使用法ではないことも主張します。 checkbashisms
は、移植可能なsh
スクリプト(Debianポリシーのsh
仕様、POSIXのスーパーセットによる)を作成するのに役立つツールで、sh
がbash
へのシンボリックリンクであるシステムでスクリプトを作成する人によって導入された非標準構文を識別するのに役立ちます。
_.profile
_はさまざまなシェルによって解釈され、その多くはPOSIXに準拠していません。通常、ログインシェルとしてsh
を使用しませんが、より高度なインタラクティブ機能を備えたzsh
、fish
、bash
などのシェルを使用します。
bash
およびzsh
、sh
として呼び出されない場合、およびそれぞれのプロファイルセッションファイル(_.bash_profile
_、_.zprofile
_)がPOSIX準拠ではない(特にzsh
)場合でも、_.profile
_を読み取ります。
したがって、_.profile
_に必要なPOSIX構文ではありませんが、POSIX(sh
)、bash
、およびzsh
と互換性のある構文です(これらのシェルを使用する場合は、Bourneでも_.profile
_ですが、Linuxベースのシステムでは一般的には見つかりません)。
checkbashisms
は間違いなくbashismsを見つけるのに役立ちますが、zsh
またはbash
と互換性のないPOSIX構文を指摘しない場合があります。
ここで、bash
固有のコード(対話型ログインシェルで_~/.bashrc
_を読み取らないbash
バグの回避策など)を使用する場合、_~/.bash_profile
_を実行することをお勧めします。それ(通常のセッション初期化を配置する_~/.profile
_をソーシングする前または後)。
通常は$0
この目的のために。あなたがそれをリンクしたサイトには立っています:
0
(Zero.) Expands to the name of the Shell or Shell script.
通常、シェル環境変数はデフォルトのシェルを示します。 .bashrcファイルを手動でソースする必要はありません(trueは以下を参照)。bashは、$ HOMEディレクトリにあることを確認するだけで、これを自動的に行う必要があります。
他のオプションは次のようなことです:
ps -o cmd= $$
これは、現在のプロセスのコマンド(引数なし、=なしの=は列ヘッダーを表示しません)を通知します。出力例:
$ps -o cmd= $$
bash
$sh
$ps -o cmd= $$
sh
更新:
立て直しました! :)
.bashrcは、以下のコメントや https://stackoverflow.com/questions/415403/whats-the-difference-between-bashrc-bash-profile-and-environment で言及されているように、常に供給されているとは限りません=
したがって、.bashrcを.bash_profileに移動して、テストを行わなくても機能するかどうかを確認できます。そうでない場合は、上記のテストがあります。
質問は、ユーザーのloginシェルとcurrentシェルを要求しますcheckbashisms
を緩和する方法で。それがユーザーがログインしたシェルである場合、/etc/passwd
のシェルを使用します。たとえば、
MY_UID=$(id -u)
MYSHELL=$(awk -F: '$3 == '$MY_UID'{ print $7; }' </etc/passwd )
もちろん、ユーザーはログイン後に新しいシェルを起動できます。もちろん、一方がbashでもう一方がbashでない場合、bashの環境変数のテストは役に立たない場合があります。
getent
ファイルだけではなくpasswd
を使用したい場合もあります(ただし、これは問題の範囲には含まれません)。
LDAPに関するコメントと logname
の提案に基づいて、この代替形式を使用できます。
MY_NAME=$(logname)
MYSHELL=$(getent passwd | awk -F: '$1 ~ /^'$MY_NAME'$/ {print $7;}' )
テスト中、logname
はリダイレクトされる入力が好きではないことに気付きました(そのため、式を分割したままにしました)。クイックチェックは、getent
が上記のプラットフォームで機能することを示しています(ただし、元の質問で提供されているはずです)。