シェルベースの「スイッチ」

シェルベースの「スイッチ」

私の考えでは源泉(つまり。呼ぶ)すべてのシェルのスクリプト(bash / cshが主なターゲットですが、Fish、zsh、ksh、およびrcも興味深いです)。

私はスクリプトが単一のファイルであることを望みました。つまり、各シェル方言のファイルではありません。

私はこれを行うことができますか?

私は次のことを考えています:

  if shell is bash then
    # bash code here
  else
    if shell is csh then
      # csh code here
    else
      if shell is xxxsh then
        # xxxsh code here
      fi
    endif
  fi

だから私はこれを行うことができます:

csh% source my_script
bash$ . my_script

問題は - もちろん、ifすべての方言が異なるため、すべてのシェルで動作する構文を使用する必要があるということです。

編集する

シェルを検出することが最初のステップです。実行時にスクリプトからシェルを決定するよかったです。

同様に重要なステップは、他のシェルを混同しないように、シェルの他の部分でコードを参照する方法です。考えてみましょう:<<here_documentbashでは許可されていますが、他のシェルでは違法なすべての組み合わせのすべての文字を他のシェルと混同せずにbashセクションにどのように含めることができますか?回答/リンクされた回答のどれもこれに対処しません。

答え1

すべてのシェルに対してコードスニペットを作成しないでください。ほとんどのシェルで解釈できる移植可能なコードのみを記述する必要があります。あなたは少し見なければなりません。POSIX シェルコマンド言語。これは、シェル(POSIX以降)がコードを解釈する方法の標準です。

多くのシェル(たとえばbash)をPOSIXシェルのように実行するように設定できます。各シェルには独自の機能と特定のシンボルがあります。移植可能なスクリプトでは完全に使用しないでください。

答え2

cshに似た状況とBourneに似た状況では、次のことができます。

start=:#||:<<"goto end="

echo "(t)csh code here"
if { bindkey >& /dev/null } then
  echo tcsh
endif

goto end=

echo Bourne-like code here
if [ -n "$BASH_VERSION" ]; then
  echo bash
fi

end=:

説明する:

  • start=:では、ラベル宣言cshと変数の代入として扱われるので、sh2つの無害な作業です。
  • では注釈リーダーとみなされますがstart=:#、では別のタグではないのでそうではありません。したがって、次の内容はコメントアウトされていますが、コメントアウトされませんでした。#cshshcshsh
  • 変数の割り当てはsh正常終了ステータス(割り当てにコマンド置換が含まれていない限り)なので、オペレータの||コマンド権限では実行されません。
  • コマンドは:<<"goto end="...goto end実行されませんが、解析され無視されます("goto end"ここではドキュメント内のさまざまな拡張を防ぐという事実が引用されています)。ただし、注:Bourneシェル(Bourneシェルのみ)では、一時ファイルは引き続き作成されます。
  • goto end=したがって、Bourneのようなシェルでは、全体の部分は無視され、間の部分はcsh。 (Bourneなどのシェルから無害な変数を割り当てる)goto end=が原因で発生します。cshend=:

シェルのサポートを増やすほど、難しくなります。fish特にスクリプト全体の構文はもちろん、実行されない部分までチェックするので難しいです。

また見なさい:

答え3

これをやろうとする理由は移植性のためだと思います。上記の答えは手がかりを提供します。 Bourneシェル(sh)が最小の共通分母であり、「すべての場所」(Linux、Solaris、Unix、AIXなど)で使用できると仮定すると、スクリプトの先頭に追加してすべての#!/bin/shスクリプトを作成できます。 shの機能のみを使用します。 (私の考えでは、LinuxではbashがBourneシェルの親セットであるため、shはbashのエイリアスですが、関係なく動作し続ける必要があります。)

常に存在すると仮定して少し改善してくださいsh。しかし、高度なシェルの追加のパフォーマンスと便利さを望むかもしれません。したがって、script.bash、script.zsh、script.ksh、script.cshなど、サポートする各シェルのスクリプトバージョンを作成できます。各スクリプトは独自の shebang 行で始まり、スクリプト内で開始されます。 shファイルを使用すると、次のように言うことができます。

#!/bin/sh
if [[ -e /bin/ksh ]] ; then 
 ./script.ksh
 exit
elif [[ -e /bin/csh ]] ; then
 ./script.csh
 exit
fi

など。

追加の提案は、自動ツールツールバーのソースコードを研究することです。 ./configure を実行すると実行されます。 GNUの人々は、スクリプトがすべての環境で実行されるようにするために多くの賢いタスクを実行します。

関連情報