#!/ bin / shと#!/ bin / bashの違いは何ですか?


281

書いたら

#!/bin/bash
echo "foo"

または

#!/bin/sh
echo "foo"

どちらも同じ結果になります。#!/bin/shまたはで始まるスクリプトを見ました#!/bin/bash。それらの間に違いはありますか?

回答:


242

bashそしてsh2つの異なるシェルです。基本的にbashsh、より多くの機能とより良い構文を備えています。ほとんどのコマンドは同じように機能しますが、異なっています。

そうは言っても、/bin/shほとんどのシステムではシンボリックリンクであり、を呼び出さないことに注意してくださいsh。UbuntuではLinuxディストリビューションの典型的な動作に/bin/shリンクしてbashいましたが、現在はdashと呼ばれる別のシェルへのリンクに変更されています。を使用しますがbash、これはほぼ標準であるため(または、私の経験からは少なくとも最も一般的です)。実際、bashスクリプトが使用されると問題が発生します。#!/bin/shこれは、スクリプト作成者が、リンクが不要であるbash場合にリンクを想定しているためです。

詳細については、http://man.cx/sh、http://man.cx/bash参照してください


25
最初の段落は非常に誤解を招く恐れがあります。「sh」はまったくシェルではなく、現在構成されているシステムシェルへのシンボリックリンクであり、Linuxシステムでは通常bashまたはdash(後者を使用するUbuntuの最新バージョン)です。
-thomasrutter

19
/bin/sh1977年にはbourne shellと呼ばれていたシェルでした。bashは/ bin / sh互換のシェルで、posix準拠のbourneシェルの代替として使用できます。 en.wikipedia.org/wiki/Bourne_shell
アレックス14

5
bashは事実上の標準(非常に広く使用されています)ですが、「標準」ではありません。Ubuntuのshは、Posix準拠のシェルであるdashを使用するため、実際に標準です。私のアドバイスは、スクリプティング、特にサーバー側のスクリプトにできるだけ頻繁にダッシュを使用することです。が、bashがより表現され、ダッシュが速く、非常に多くのことを実行し、より安全です。
リック-777 14

@ Rick-777では、スクリプトの先頭に#!/ bin / dashを明示的に配置する必要がありますか?また、コマンドを記述して./scriptNameを使用して実行するだけのスクリプトも作成しましたが、これは正常に機能しました。#!/ bin / yourShellHereは必要ですか?
user137717

@ Rick-777#!/ bin / shellNameを除外する場合、ファイルにfileName.shという名前を付けました。#!/ bin / shを宣言せずに、優先システムシェルに暗黙的にリンクしますか?
user137717

82

Linuxおよびその他のUnixライクシステムでは、複数のシェルを選択できます。

シェルは、小さなプロンプトを描画するだけでなく、特にパイプや条件などの複雑なロジックを配置する場合は、コマンドを解釈します。

bashは、Linuxシステムのユーザーのデフォルトシェルとして使用される最も一般的なシェルです。これは、Unixの歴史全体で使用されている他のシェルの精神的な子孫です。その名前は、 bashはBourne-Again Shellの略語で、CシェルとKornシェルの機能も組み込まれていますが、Bourneシェルへのオマージュです。

最近では、から実行/bin/bashされています-bashを使用するシステムであれば、ここからアクセスできます。

ただし、シェルを使用するのはユーザーだけではありません。スクリプト(シェルスクリプト)を解釈するには、シェルが必要です。シェルスクリプトを実行する場合、システムはシェルプロセスを起動してスクリプトを実行する必要があります。

問題は、シェルごとにわずかな不整合があり、スクリプトの実行に関しては、実際の問題になる可能性があることです。 bashには、bashのみに固有のスクリプト機能が非常に多くあり、他のシェルにはありません。常にbashを使用してこれらのスクリプトを実行する場合、これは問題ありません。他のシェルは、bashをエミュレートしようとするか、POSIX標準に準拠しようとします。POSIX標準は、bashが非常によくサポートします(ただし、独自の拡張機能を追加します)。

シェルスクリプトの先頭で、シェバンを使用して実行するシェルを指定することができます。スクリプトは#!/bin/bash最初の行で指定できます。つまり、スクリプトは常に別のシェルではなくbashで実行する必要があります。

/ bin / shは、システムシェルを表す実行可能ファイルです。実際には、通常、システムシェルであるシェルの実行可能ファイルを指すシンボリックリンクとして実装されます。システムシェルは、システムスクリプトが使用するデフォルトのシェルの一種です。Linuxディストリビューションでは、長い間、これは通常bashへのシンボリックリンクであったため、常に/ bin / shをbashまたはbash互換シェルにリンクするという慣習になりました。しかし、過去数年でDebian(およびUbuntu)はシステムシェルをbashからdashに切り替えることを決定しました-同様のシェル-/ bin / shにbashを使用するというLinux(まあ、GNU)の長い伝統を破ります。Dashは、起動速度(およびパッケージインストールスクリプトなどの多くのシェルスクリプトを必要とする他のもの)に有益な、より軽量ではるかに高速なシェルと見なされます。

Dashはbashとかなり互換性があり、同じPOSIX標準に基づいています。ただし、bash固有の拡張機能は実装していません。#!/bin/shシバンとして(システムシェル)を使用するスクリプトが存在しますが、bash固有の拡張機能が必要です。これは現在、DebianとUbuntuによって修正されるべきバグと考えられています。DebianとUbuntuは、ダッシュを指すと/ bin / shが動作できるようにする必要があります。

Ubuntuのシステムシェルはダッシュを指していますが、ユーザーとしてのログインシェルは現時点では引き続きbashです。つまり、Linuxのどこかでターミナルエミュレータにログインすると、ログインシェルはbashになります。シェルを対話的に使用する場合、操作の速度はそれほど問題ではなく、ユーザーはbashに精通しています(また、ホームディレクトリにbash固有のカスタマイズがある場合があります)。

スクリプトを書くときに使用すべきもの

スクリプトにbashでのみサポートされる機能が必要な場合は、を使用します#!/bin/bash

ただし、可能な場合は、スクリプトがPOSIX互換であることを確認し#!/bin/sh、どのインストールでも常に確実に優先されるPOSIX互換のシステムシェルを指すuseを使用することをお勧めします。


18

前の回答に加えて、への/bin/shシンボリックリンクである場合でも/bin/bash#!/bin/shと完全に同等ではありません#!/bin/bash

bash(1)のmanページ

「bashがshという名前で呼び出された場合、POSIX標準にも準拠しながら、shの履歴バージョンの起動時の動作を可能な限り模倣しようとします。」

たとえば、bash固有の構文:

 exec  > >(tee logfile.txt)

#!/bin/shsh-> bashシンボリックリンクが設定されている場合でも、で始まるシェルでエラーが発生します。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.