現在のシェルを決定するためにcheckbashismに従います。

現在のシェルを決定するためにcheckbashismに従います。

鉱山では、.profileログインシェルが実際に実行されたときに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

現在、シェル構成ファイル、スクリプト、および機能はバージョン管理下にあります。また、最近では、Bash関連function funcname()の機能の恩恵を受けていないシェルスクリプトからランダムBashismを削除し始めましたfuncname()

私のシェルファイルストアの場合は設定しました。事前コミットcheckbashismsDebian ユーティリティを実行するためのフック開発スクリプトパッケージsh誤ってBash関連の構文を導入しないように、リポジトリ内のすべてのファイルを削除してください。ただし、これによりエラーが発生します.profile

possible bashism in .profile line 51 ($BASH_SOMETHING):
if [ "${BASH_VERSION:-}" ]; then

どのシェルが実行されているかを確認し、.NETで実行しない方法があるかどうか疑問に思いますcheckbashisms

リストを確認しました。POSIX リストされたシェル関連変数これらのいずれかを使用して現在のシェルを表示できることを願っています。また、インタラクティブなDashシェルで設定された変数を調べましたが、適切な候補を見つけることができませんでした。

.profile現在は;の処理を除外しました。checkbashismsファイルサイズが小さく、手動で確認するのは難しくありません。しかし、この問題を調査した後でも、どのシェルが実行されているかを確認するPOSIX準拠の方法(または少なくともcheckbashismsエラーを引き起こさない方法)があるかどうかはまだ疑問に思います。


追加の背景/説明

シェル構成ファイルをバージョン管理にする理由の1つは、現在定期的にログインしているすべてのシステム(Cygwin、Ubuntu、およびCentOS(5および7、ユーザー認証にActive Directoryを使用))で自分の環境を構成することです。私はX Windows /デスクトップ環境とSSHを介してリモートホストにログインすることがよくあります。しかし、私はこれが将来に備えて、システムの依存関係や他のツールへの依存関係をできるだけ最小限に抑えたいと思います。

checkbashisms私はシェル関連ファイルの構文に対して単純で自動化された完全性チェックを実行するためにこれを使用してきました。完璧なツールではありません。たとえば、command -vスクリプトで使用するときに文句を言わないようにパッチを適用しました。調査中、私はこのプログラムの実際の目的は、私が知っている限り、2008年(または2013年改訂版)ではなく、POSIX 2004ベースのDebianポリシーに準拠することを保証することでした。

答え1

通常、$0この目的に使用されます。リンクしたサイトの内容は次のとおりです。

0
   (Zero.) Expands to the name of the shell or shell script.

答え2

あなたの

# 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を設定します。が実行中であると主張すると、シェルが呼び出されたことを示すインジケータとして使用できます。 (このオプションは、POSIXLY_CORRECTが環境にある場合、または環境で、またはSHELLOPTS = posixで呼び出された場合にも設定されます。ただし、これらすべてでは、ケースはすべて呼び出されたかのように機能します。)bashbashshbash[ -o posix ]shbash-o posixbashsh


使用できるもう1つの変数は、そのオプションが渡さ$BASH_VERSIONれない限り文句を言わないようですcheckbashism。これは、実行中であることを確認するために使用できる項目にのみ適用されます。-x$BASHbashbash


私もこれが実際にcheckbashismscheckbashismsshshshbash

Aは、.profilePOSIXと互換性のないさまざまなシェルとして解釈されます。通常sh、ログインシェルとして高度なインタラクティブ機能を備えたシェルまたはシェルは使用されません。zshfishbash

bashまた、zshasが呼び出されておらず、対応するshプロファイルセッションファイル(.bash_profile.zprofile)がPOSIXと互換性がなく、zshまだ読み取れる可能性があります.profile

したがって、あなたが望むものはPOSIX構文ではなくPOSIX互換.profile構文です(一般的shです。bashzsh.profile

checkbashisms確かに答えを見つけるのに役立ちますバシズムzshただし、POSIX構文と互換性があるか互換性がない場合は指摘されないことがありますbash

ここで特定のコードを使用する場合bash(たとえば、このエラーを解決するには対話型ログインシェルから読み取らbashない~/.bashrc)、これを行うことをお勧めします(~/.bash_profileパブリックセッションを配置する前または後に~/.profile初期化)。

答え3

通常、SHELL 環境変数はデフォルトのシェルを通知します。 .bashrcファイルを手動でインポートする必要はありません(事実ではありません。以下のアップデートを参照)。 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に移動し、テストなしで動作していることを確認できます。そうでない場合は、上記のテストを実行してください。

答え4

この質問は、ユーザーに次のことを尋ねます。ログインケーシングもそうです。現在の落ち着かせる方法で皮をむきますcheckbashisms。ユーザーがログインしたシェルを意味する場合は、たとえば次のようなシェルを使用します/etc/passwd

MY_UID=$(id -u)
MYSHELL=$(awk -F: '$3 == '$MY_UID'{ print $7; }' </etc/passwd )

もちろん、ユーザーはログイン後に新しいシェルを起動できます。もちろん、1つはbashで、もう1つはbashではない場合、bashの環境変数をテストするのは役に立ちません。

getent一部の人々はファイルの代わりに使用したいかもしれませんpasswd(しかし、それは質問の範囲外です)。

LDAPに関するコメントと提案に基づいていますlogname、次の代替形式を使用できます。

MY_NAME=$(logname)
MYSHELL=$(getent passwd | awk -F: '$1 ~ /^'$MY_NAME'$/ {print $7;}' )

テスト中に入力リダイレクトが気に入らないことがわかりましたlogname(式を分離しました)。クイックチェックにより、getent前述のプラットフォームで動作する必要があることがわかります(元の質問に提供する必要があります)。

関連情報