web-dev-qa-db-ja.com

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

書いたら

#!/bin/bash
echo "foo"

または

#!/bin/sh
echo "foo"

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

273
Rahul Virpara

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

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

詳細については、 http://man.cx/shhttp://man.cx/bash

235
reverendj1

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

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

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

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

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

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

シェルスクリプトの先頭で、Shebangを使用して実行するシェルを指定できます。スクリプトは、最初の行で#!/bin/bashを指定できます。これは、スクリプトが別のシェルではなく、常にbashで実行されることを意味します。

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

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

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

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

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

ただし、可能な場合は、スクリプトがPOSIX互換であることを確認し、#!/bin/shを使用することをお勧めします。

80
thomasrutter

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

bash(1)manページ から:

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

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

 exec  > >(tee logfile.txt)

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

18
AnkiF

GNU Bash:#!/bin/bash; POSIXシェル:#!/bin/sh