通常、シェルに関連して使用される「sh互換」というフレーズを見てきました。シェル内から実行される可能性のあるプログラムにも適用されるかどうかはわかりません。
シェルまたは他のプログラムが「sh互換」であるとはどういう意味ですか? 「sh互換性がない」とはどういう意味ですか?
編集:
bashとshの違いを尋ねるこの質問は非常に関連性があります:
shとbashの違い
「sh互換」とはどういう意味か、それでも直接的な答えが欲しいです。 「sh互換」とは「シェルコマンド言語を実装する」という意味ですが、なぜ「sh互換」シェルが非常に多く、なぜそれらが異なるのでしょうか。
承認された回答:
なぜこれほど多くの「sh互換」シェルがあるのですか?
Bourneシェルは、UnixV7の一部として1979年に最初に公開されました。ほとんどすべてのUnixおよびUnixライクなシステムは、たとえ精神的にであっても、V7 Unixの子孫であるため、Bourneシェルは「永遠に」私たちと共にありました。¹
Bourneシェルは実際には以前のシェルに取って代わり、Thompsonシェルを改名しましたが、Unixの歴史の非常に早い段階で発生したため、今日ではほとんど忘れられています。 Bourneシェルは、Thompsonシェルのスーパーセットです。²
ボーンシェルとトンプソンシェルはどちらもsh
と呼ばれていました 。 POSIXで指定されたシェルは、 sh
とも呼ばれます。 。つまり、誰かが sh
と言ったとき -互換性があり、手で手を振ってこの一連のシェルを参照しています。具体的にしたい場合は、「POSIXシェル」または「Bourneシェル」と言います。³
POSIXシェルは、1988バージョンのKornShellに基づいています。これは、AT&T UnixのBourneシェルに置き換わるものであり、機能の点でBSDCシェルを飛躍的に向上させます。⁴ksh
はPOSIXシェルの祖先であり、ほとんどのUnixおよびUnixライクなシステムには、今日のKornシェルのいくつかのバリアントが含まれています。例外は通常、完全なPOSIXシェルが必要とするスペースを確保できない小さな組み込みシステムです。
とは言うものの、Kornシェルは、POSIXシェルとは別のものとして、商用のUnixの世界以外では実際に普及することはありませんでした。これは、その台頭が初期のUnix商用化に対応していたため、Unix戦争に巻き込まれたためです。 BSD Unixは、Cシェルを支持してそれを避け、そのソースコードは、開始時にLinuxで自由に使用できませんでした。⁵したがって、初期のLinuxディストリビューターがLinuxカーネルに対応するコマンドシェルを探していたとき、彼らは通常、それらの sh
の1つであるGNUBashを選択しました。 -あなたが話している互換性。⁶
LinuxとBashの間の初期の関連付けは、 ksh
を含む他の多くのシェルの運命をほぼ封印しました。 、 csh
およびtcsh
。今日でもこれらのシェルを使用しているダイハードがありますが、それらは非常に少数派です。⁷
このすべての歴史は、 bash
のような比較的後発者の作成者がなぜ 、 zsh
、および yash
それらをsh
にすることを選択しました -互換性:Bourne / POSIX互換性は、Unixライクなシステムが広く採用されるために提供しなければならない最低限のシェルです。
多くのシステムでは、デフォルトのインタラクティブコマンドシェルと / bin / sh
別のものです。 / bin / sh
可能性があります:
-
元のBourneシェル。 これは、Solaris 10(2005年にリリース)やその前身などの古いUNIX®システムで一般的です。⁸
-
POSIX認定のシェル。 これは、Solaris 11(2010)などの新しいUNIX®システムで一般的です。
-
Almquistシェル 。これは、1989年にUsenetで最初にリリースされたオープンソースのBourne / POSIXシェルクローンであり、AT&Tソースコード4.4BSD-Liteを含まない最初のBSDリリースに含めるためにBerkeleyのCSRGに提供されました。 Almquistシェルはしばしば
ash
と呼ばれます 、/ bin / sh
としてインストールされている場合でも 。4.4BSD-Liteは、
/ bin / sh
を使用して、すべての最新のBSD派生物のベースになりました。 以下に示す1つの主要な例外を除いて、それらのほとんどでAlmquist派生物として残っています。この直接の子孫は、NetBSDおよびFreeBSDのソースコードリポジトリで確認できます。これらは、1日目からAlmquistシェル派生物を出荷していました。2つの重要な
ash
があります BSDの世界の外のフォーク:-
ダッシュコード> 、2006年にDebianとUbuntuによってデフォルトの
/ bin / sh
として有名に採用されました 実装。 (Bashはデフォルトのインタラクティブのままです Debian派生のコマンドシェル。) -
ash
BusyBoxのコマンド。これは組み込みLinuxで頻繁に使用され、/ bin / sh
を実装するために使用される場合があります。 。dash
より後の日付なので そしてそれはDebianの古いash
から派生したものです パッケージ、私はそれをdash
の派生物と見なすことを選択しましたash
ではなく 、BusyBox内のコマンド名にもかかわらず。(BusyBoxには、
ash
に代わる機能の少ないものも含まれていますhash
と呼ばれます 。通常、2つのうち1つだけが任意のBusyBoxバイナリに組み込まれます:ash
デフォルトですが、hash
スペースが本当に狭いとき。したがって、/ bin / sh
BusyBoxベースのシステムでは常にdash
であるとは限りません -like。)
-
-
GNUバッシュ 、
sh
として呼び出されると、POSIX以外の拡張機能のほとんどが無効になります 。この選択は、Debianとその派生物を除いて、Linuxのデスクトップおよびサーバーバリアントで一般的です。 Mac OS Xも、2003年にリリースされたPanther以来これを行ってきました。
-
ksh93
のシェル POSIX拡張機能 、OpenBSDのように。 OpenBSDシェルは、sh
として呼び出されたときに、BourneおよびPOSIXシェルとの構文およびセマンティックの非互換性を回避するために動作を変更しますが 、古いシェルと競合しない純粋な拡張機能を無効にすることはありません。これは一般的ではありません。
ksh93
を期待するべきではありません/ bin / sh
の機能 。
上記の「シェルスクリプト」は、Bourne/POSIXシェルスクリプトを意味する一般的な用語として使用しました。これは、ボーン家の砲弾が遍在しているためです。他のシェルでのスクリプトについて話すには、「Cシェルスクリプト」のような修飾子を指定する必要があります。 Cファミリシェルがデフォルトのインタラクティブシェルであるシステムでも、スクリプトにはBourneシェルを使用することをお勧めします。
ウィキペディアがUnixシェルを分類するとき、それらをBourneシェル互換、Cシェル互換、および「その他」にグループ化することを示しています。
関連:Ubuntuシステム上のすべてのユーザーを一覧表示するユーザーフレンドリーなコマンド?この図は役立つかもしれません:
(SVGバージョン(31 kB)をクリックするか、フルサイズのPNGバージョン(218 kB)を表示します。)
「sh互換性がない」とはどういう意味ですか?
sh
について話している人 -互換性のないものとは、通常、次の3つのいずれかを意味します。
-
それらはそれらの「他の」シェルの1つを参照しています。⁹
-
彼らはボーンとCシェルファミリーを区別しています。
-
彼らは、他のすべてのボーンファミリーシェルにはない、1つのボーンファミリーシェルの特定の機能について話している。
ksh93
、bash
、およびzsh
特に、古い「標準」シェルには存在しない多くの機能があります。共有POSIX/ksh88
を超えると、これら3つは多くの点で相互に互換性がありません。 ベース。
#!/ bin / sh
を使用してシェルスクリプトを作成するのは典型的なエラーです。 上部にシバンラインがありますが、内部でBashまたはKornシェル拡張を使用します。 / bin / sh
以降 は、最近の多くのシステムでの上記のKorn / POSIXファミリ図のシェルの1つです。このようなスクリプトは、記述されているシステムでは機能しますが、 / bin / sh
のシステムでは失敗します。 幅広いボーンファミリーのシェルからのものです。ベストプラクティスは、#!/ bin / bash
を使用することです または#!/ bin / ksh
スクリプトがそのような拡張機能を使用している場合は、シバン行。
特定のBourneファミリシェルスクリプトが移植可能かどうかを確認する方法はたくさんあります:
-
checkbashisms
を実行します その上で、スクリプトの「バシズム」をチェックするDebianプロジェクトのツール。 -
posh
の下で実行します 、SUS3で指定された機能のみを意図的に実装するDebianパッケージリポジトリのシェルと、その他のいくつかのマイナーな機能。 -
obosh
で実行します Schily Toolsプロジェクトから、2005年にOpenSolarisの一部としてSunによってオープンソース化されたBourneシェルの改良版であり、最新のコンピューターで1979スタイルのBourneシェルを取得する最も簡単な方法の1つになっています。Schily Toolsディストリビューションには、
bosh
も含まれています 、多くの非標準機能を備えたPOSIXタイプのシェルですが、すべてのPOSIXファミリシェルで実行することを目的としたシェルスクリプトの互換性をテストするのに役立つ場合があります。bash
よりも機能セットが保守的である傾向があります 、zsh
およびksh93
の拡張バージョン 。Schily Toolsには、
bsh
というシェルも含まれています 、しかしそれはボーン家の殻ではない歴史的な奇妙なことです。 -
GNUAutoconfマニュアルのポータブルシェルプログラミングの章を読んでください。スクリプトで説明されている問題のある構成のいくつかに気付くかもしれません。
なぜ違うのですか?
同じ理由で、すべて「新しく改善されました!」物事は異なります:
-
改善されたバージョンは、下位互換性を破ることによってのみ改善できました。
-
誰かが何かを機能させるための別の方法を考えました。彼らはそれが好きですが、それは古いものが機能した方法と同じではありません。
-
誰かが古い標準を完全に理解せずに再実装しようとしたため、混乱して意図しない違いが生じました。
脚注と傍白 :
-
BSD Unixの初期のバージョンは、V6Unixの単なるアドオンソフトウェアコレクションでした。 BourneシェルはV7までAT&T Unixに追加されていなかったため、BSDは技術的にBourneシェルの導入を開始しませんでした。 Thompsonシェルの原始的な性質に対するBSDの答えは、Cシェルでした。
それにもかかわらず、BSDの最初のスタンドアロンバージョン(2.9BSDおよび3BSD)は、V7またはその後継のポータブルUNIX / 32Vに基づいていたため、 Bourneシェルを含めます。
(2BSDラインはDigitalのPDPミニコンピューター用のBSDのパラレルフォークになりましたが、3BSDおよび4BSDラインはVaxenやUnixワークステーションなどの新しいコンピュータータイプを利用していました。2.9BSDは本質的に4.1cBSDのPDPバージョンでした。同時期の共有コード。VAXが到着したときにPDPが消えただけではなかったため、2BSDラインはまだ動き回っています。)
Bourneシェルは1983年までにUnixの世界のいたるところにあったと言っても過言ではありません。これは、コンピューティング業界の「永遠」に近いものです。 MS-DOSは、その年に階層型ファイルシステム(awww、なんて素晴らしい!)と、9インチの白黒画面を備えた最初の24ビットMacintoshを手に入れました。グレースケールではなく、文字通り黒 および白 —来年の初めまで出てこないでしょう。
-
Thompsonシェルは、今日の基準では非常に原始的でした。これは、今日期待されているスクリプトプログラミング環境ではなく、対話型のコマンドシェルにすぎませんでした。パイプやI/Oリダイレクトのようなものがありましたが、これは典型的には「Unixシェル」の一部であると考えられているため、MS-DOSコマンドシェルはそれらをUnixから取得していると考えています。
BourneシェルもPWBシェルに取って代わり、プログラム可能性(
if
など)のような重要なものをThompsonシェルに追加しました。 、switch
およびwhile
)および初期の形式の環境変数。 PWBシェルは、Unixのすべてのバージョンの一部ではなかったため、Thompsonシェルほど記憶に残っていません。 -
誰かがそうでないとき POSIXとBourneシェルの互換性について具体的に言うと、それらが意味する可能性のあるものは多岐にわたります。
極端な場合、彼らは1979年のBourneシェルをベースラインとして使用している可能性があります。 「
sh
この意味での「互換性のあるスクリプト」とは、真のBourneシェルまたはその後継とクローンのいずれかで完全に実行されることが期待されることを意味します:ash
、bash
、ksh
、zsh
、など。もう一方の極端な人は、代わりにPOSIXによって指定されたシェルをベースラインとして想定しています。最近では、POSIXシェルの機能の多くを「標準」として採用しているため、Bourneシェルには実際には存在していなかったことを忘れがちです。組み込みの演算、ジョブ制御、コマンド履歴、エイリアス、コマンドライン編集、
$()
コマンド置換の形式など。 -
Kornシェルのルーツは1980年代初頭にさかのぼりますが、AT&Tは1988年のSystem Vリリース4までUnixで出荷しませんでした。非常に多くの商用UnixがSVR4に基づいているため、これにより
ksh
1980年代後半以降のほぼすべての関連する商用Unixで。(SVR3以前に基づいたいくつかの奇妙なUnixフレーバーは、SVR4のリリース後も市場の一部に保持されていましたが、革命が起こったとき、それらは最初に壁にぶつかりました。)
1988年は、Kornシェルベースの「POSIXシェル」を備えた最初のPOSIX標準が発表された年でもあります。その後、1993年に、Kornシェルの改良版が発表されました。 POSIXはオリジナルを効果的に配置したため、
ksh
2つのメジャーバージョンに分岐:ksh88
およびksh93
、彼らの分裂に関与した年にちなんで名付けられました。ksh88
違いはわずかですが、完全にPOSIX互換ではないため、ksh88
の一部のバージョンは シェルはPOSIX互換になるようにパッチが適用されました。 (これは、Dr。David G. KornとのSlashdotに関する興味深いインタビューからのものです。はい、シェルを書いた人です。)ksh93
POSIXシェルの完全に互換性のあるスーパーセットです。ksh93
での開発 プライマリソースリポジトリがAT&TからGitHubに移動して以来、散発的になっています。最新のリリースは、私がこれを書いている時点で約3年前のものです。ksh93v。 (プロジェクトのベース名はksh93
のままです 1993年以降のリリースバージョンを示すためにサフィックスが追加されています。)POSIXシェルとは別のものとしてKornシェルを含むシステムでは、通常、
/ bin / ksh
として利用可能になります。 、時々それは他の場所に隠れていますが。ksh
について話すとき または名前でKornシェル、私たちはksh93
について話している 下位互換性のあるBourneおよびPOSIXシェルサブセットと区別する機能。純粋なksh88
に出くわすことはめったにありません 今日。 -
AT&Tは、2000年3月までKornシェルのソースコードを独占的に保持していました。その時点までに、LinuxとGNUBashとの関係は非常に強力でした。 Bashと
ksh93
それぞれに利点がありますが、この時点で慣性によりLinuxはBashと緊密に関連付けられています。初期のLinuxベンダーが最も一般的に
pdksh
よりもGNUBashを選択する理由について 、だった Linuxが始まったときに利用可能でしたが、それは、残りのユーザーランドの多くがGNUプロジェクトからのものだったためだと思います。 Bashは、pdksh
よりもいくらか高度です。 、Bash開発者はKornシェル機能のコピーに制限されていないためです。pdksh
で作業する AT&Tがソースコードを真のKornシェルにリリースした頃に停止しました。ただし、まだ維持されている2つの主要なフォークがあります。OpenBSDpdksh
およびMirBSDKornShell、mksh
。mksh
が面白いと思います Cygwin用に現在パッケージ化されている唯一のKornシェル実装です。 -
GNU Bashは多くの点でPOSIXを超えていますが、より純粋なPOSIXモードで実行するように要求できます。
-
csh
/tcsh
通常、1990年代初頭までBSDUnixのデフォルトのインタラクティブシェルでした。BSDバリアントであるため、Mac OS Xの初期バージョンは、Mac OSX10.2「ジャガー」を介してこのようになりました。 OSXはデフォルトのシェルを
tcsh
から切り替えました OSX10.3「Panther」でBashに。この変更は、10.2以前からアップグレードされたシステムには影響しませんでした。これらの変換されたシステムの既存のユーザーは、tcsh
を保持していました シェル。FreeBSDはまだ
tcsh
を使用していると主張しています デフォルトのシェルとしてですが、ここにあるFreeBSD 10 VMでは、デフォルトのシェルはPOSIX互換のAlmquistシェルバリアントの1つであるように見えます。これはNetBSDにも当てはまります。OpenBSDは
pdksh
のフォークを使用します 代わりにデフォルトのシェルとして。LinuxとOSXの人気が高いため、FreeBSDもBashに切り替えることを望む人もいますが、哲学的な理由から、すぐにはそうなることはありません。気になる場合は、簡単に切り替えることができます。
-
/ bin / sh
のように真にバニラなBourneシェルを備えたシステムを見つけることはめったにありません。 この日。互換性テストのために、それに十分に近いものを見つけるために邪魔にならないようにする必要があります。現代のコンピューターで本物の1979年のビンテージBourneシェルを実行する唯一の方法を知っています。それは、コンピューター履歴シミュレーションプロジェクトのSIMHPDP-11シミュレーターでAncientUnixV7ディスクイメージを使用することです。 SIMHは、Unixライクなコンピュータだけでなく、ほとんどすべての最新のコンピュータで動作します。 SIMHはAndroidとiOSでも動作します。
Sunは、OpenSolarisを使用して、SVR4バージョンのBourneシェルを初めてオープンソース化しました。それ以前は、BourneシェルのV7以降のバージョンのソースコードは、Unixソースコードライセンスを持っている人だけが利用できました。
このコードは、いくつかの異なるソースから、廃止されたOpenSolarisプロジェクトの残りの部分とは別に入手できるようになりました。
最も直接的な情報源は、HeirloomBourneシェルプロジェクトです。これは、OpenSolarisの最初の2005リリースの直後に利用可能になりました。移植性とバグ修正作業の一部は、今後数か月にわたって行われましたが、その後、プロジェクトの開発は中止されました。
JörgSchillingは、このコードのバージョンを
obosh
として維持するためのより良い仕事をしました。 彼のSchilyToolsパッケージで。詳細については、上記を参照してください。2005年のソースコードリリースから派生したこれらのシェルには、マルチバイト文字セットのサポート、ジョブ制御、シェル関数、および元の1979年のBourneシェルにはないその他の機能が含まれていることに注意してください。
元のBourneシェルを使用しているかどうかを確認する方法のひとつは、Thompsonシェルからの移行を容易にするために追加されたドキュメント化されていない機能をサポートしているかどうかを確認することです。
^
|
のエイリアスとして 。つまり、ls ^ more
のようなコマンド KornまたはPOSIXタイプのシェルではエラーが発生しますが、ls|のように動作します。詳細
真のBourneシェルで。 -
時折、
魚
に遭遇することがあります 、scsh
またはrc/ es
順守していますが、Cシェルファンよりもさらにまれです。rc
シェルのファミリはUnix/Linuxシステムでは一般的に使用されていませんが、このファミリは歴史的に重要であり、上の図でその地位を獲得した方法です。rc
は、ベル研究所のオペレーティングシステム設計に関する継続的な調査の一環として作成された、第10版Unixの後継の一種であるベル研究所オペレーティングシステムのPlan9の標準シェルです。プログラミングレベルでは、BourneシェルとCシェルの両方と互換性がありません。おそらくそこに教訓があるでしょう。rc
の最もアクティブなバリアント Unixのrc
に基づくTobyGoodwinによって保守されているようです。 バイロン・ラキジスによるクローン。