/ bin / bashではなく/ bin / shを指すシェバンを持つ理由はありますか?


53

私が見たほとんどのシェルスクリプト(自分で書いていないスクリプトを除く)で、シバンがに設定されていることに気付きました#!/bin/sh。これは古いスクリプトでは本当に驚かないが、かなり新しいスクリプトでもそうだ。

好むための何らかの理由がある/bin/sh以上は、/bin/bash以来、bash十年以上前にうまくいって、多くのLinuxやBSDマシン上で、かなり多くの遍在し、多くの場合、デフォルト?


23
/bin/sh特定のbash機能を使用しない場合に使用するとよいでしょう。ある日、スクリプトがインストールされていないシステム(リモートサーバー、組み込みコンピューター...)でスクリプトの1つを使用しなければならない可能性があります
Mathieu

1
一般に、意見に基づいた回答に役立つ質問をすることは避けるべきです(これは、この質問に答えることができると信じている唯一の方法です-しかし、それは私の意見です
mikeserv

9
長年にわたってこの問題に取り組んでいる少なくとも2つの組織を指して、歴史と結果を見ることによって、単なる意見を伴わずにこの質問に答えることができると信じています。さらに多くの読み物を添付して、ブートします。☺
JdeBP

3
@JulesMazur ...the answers so far are fairly subjective...「主観的な」ステートメントは、本質的に意見に基づいています。/bin/bashbashが明示的に必要な場合にのみ使用してください。開発者としての40年以上前、ずっと前にbash、テスト時を除いて、明示的にそれを必要とすることはほとんどなかった。(シェル拡張も避けるよう努めていますが、私のスクリプトのほとんどは配布を目的としています。)ネット上の多くのスクリプトは、広く使用することも目的としています。
user2338816

2
@ user2338816私の悪い、私は客観的を意味しました。あなたのポイントをありがとう!
ジュール

回答:


83
  1. デフォルトではbashを出荷しないシステムがあります(例:FreeBSD)。
  2. bashがインストールされていても、にない場合があり/binます。
  3. ほとんどの単純なスクリプトはbashを必要としません。
  4. POSIXシェルを使用する方が移植性が高く、スクリプトはさまざまなシステムで実行されます。

17
別の理由:多くの場合、/ bin / shはbashよりも高速であるか、少なくともロードが高速です(小さいため)。
derobert

5
@derobert、/bin/shより速く、それはない場合でbash、まだOS / XまたはRHELのようないくつかのシステムが存在している、/bin/shであるがbash
ステファンシャゼル

1
いいえ。bashには後方互換性があるため、一部のOSはこれをリンクします。
Sobrique

7
かなりの数のスクリプトがそれを想定して/bin/sh/bin/bashます。Ubuntuがbashからdashに切り替えると、それらすべてが壊れました。
atamanroman

19
@atamanroman:そもそもスクリプトは正しくありませんでした。Bashが必要な場合は、スクリプトを使用すべき#!/bin/bashでした(何も問題はありません!)。変更は主にDebianの上流で行われました。ユーザーエクスペリエンスが向上し、システムの起動時間に測定可能な影響がありました。また、セキュリティに良い影響を与えました。「Shellshock」を参照してください。
ディートリッヒEpp

28

(Debian関連:Ubuntu、Mintなど)Linuxのほとんどのシステムスクリプトは、これらのシステムのデフォルトの/ bin / shである高速ダッシュで実行するように記述されています。理由は2つあります。

  • システムの速度。ダッシュのコードが小さいほど、読み込みが速くなり、実行も速くなります。シェルスクリプトのプログラマーに多少の(小さな?)追加の労力(コスト)をかけます。

  • セキュリティ。シェルの多様性は、バグに対する回復力に役立ちます。デフォルトのシェルにはこのような脆弱性がなかったため、Debianシステムはほとんどshellshockに対して脆弱ではありませんでした。

実際、Bashはより強力で、コーディングを容易にする要素がはるかに多いため、ユーザーのデフォルトのシェルです。またsh、Mac OS のデフォルト(/ bin / shからリンクされているもの)です。ただし、bashというリンク名で呼び出すと、shposix準拠のシェルとして起動します。


2
より単純なシェルの利用可能なツールのより限られたセットは、それのためのコードの記述をより困難にします(これに対する狂信的な戦争を避けてください)。そのため、一部のユーザーは、bashよりも多くのツールを使用できるzshが好きです。両方の両極端のバランスであるように、私はBashがより好きです。

4
@ RobertL、kshで追加されbashで採用された機能の多くは、堅牢で正しいスクリプトを記述するプロセスを大幅に容易にするために存在します。たとえば、間接的な割り当てと評価を安全に実行できるようにするさまざまな追加機能がない場合、eval付随するセキュリティの危険性があるを使用して自分自身を見つけることができます。同様に、内蔵されていない正規表現サポート、一方が等、単一のライン内に一致させるための(重性能ペナルティに)外部コマンドを使用する必要ができる
チャールズ・ダッフィー

1
@ RuiFRibeiro、Debianでは静的にリンクされているものはありません。Dashはより制限されていますが、主にインタラクティブ機能(補完なしなど)で制限されているため、スクリプトの方が高速です。
Jan Hudec

21

他の人たちは、Bourne Againシェルがデフォルトであり、どこにでもあるという質問の前提がまったく間違っていると指摘しています。

それに加えて、シェルスクリプトの解釈にBourne Againシェル以外の何かを使用することには、確かに十分な理由があります。これらの理由は、長年にわたってUbuntuとDebianの大きなプロジェクトをやる気にさせ、システムの初期化(System 5の多くのシェルスクリプトであったrc)とパッケージのインストール/削除によって、多くのシェルスクリプトを実行するようにしました。 Bourne Again シェルの代わりのDebian Almquistシェル

簡単に言えば、Bourne Againシェルは、インタラクティブな機能がそのまま詰まっていますが、POSIX準拠のシェルスクリプトの最速のシェルインタープリターではありません。したがって、シェルスクリプトをPOSIXに準拠させ、Debian Almquistシェルなどのより軽量なプログラムで解釈できるようにすると、システムのパフォーマンスが向上します。(最終的に、DebianはAlmquistシェルにわずかな調整を加えて、単純に深すぎて広く埋め込まれ、削除するには役に立たないいくつかの非POSIXシェル構成のサポートを追加する必要がありました。)

その結果、ブートストラップのパフォーマンスが大幅に向上しました。

そのため、考慮すべきシェルには2つの異なるクラスがあります。

  • アカウントデータベース内のユーザーの対話型ログインシェルとして構成されている、派手な対話型機能をすべて備えたシェル
  • シェルスクリプトプログラムによってスクリプトインタープリターとして使用される、多くのスクリプトを迅速に解釈するシェル。

これを「優先する/bin/sh」と言うのは簡単すぎます。Debianには、実際には少なくとも2つの目標がありました。

  1. Debian Almquistシェル、Zシェル(POSIXモード)、Bourne Againシェル(POSIXモード)、MirBSD Kornシェルなどを使用している管理者に直面して/bin/sh、…

    1. …スクリプトを可能な限り移植可能にし、/bin/shマッピング先を切り替えても問題が発生しないようにしました。または

    2. …移植性のないスクリプトを作成して、単にそのマップを期待するのではなく、正しいインタープリタープログラムをターゲットにします/bin/sh

  2. DebianのAlmquistがためにデフォルトのマッピングをシェル作っていた/bin/shので、それらのスクリプトこと、代わりのBourneシェルのだった POSIX準拠(または、より適切に、Debianポリシーマニュアルに準拠)がより迅速に実行しました。

そしてもちろん、一度これに取り組むと、さらに多くのことができます。そのようなの同類の効率のトレードオフを考慮するように/bin/trueし、/usr/bin/clearシェルスクリプトやコンパイルされたプログラムです。しかし、幸いなことに、これはこの答えの範囲を超えています。☺

もちろん、これはまったく新しいものではなく、Unix固有のものでもありません。戻る世紀の変わり目の前に、私はそのDOCOで、この非常に分裂を説明するとの違いを指摘、書いて、両方の「インタラクティブ」と「非対話型」の味に来たコマンドラインインタプリタを公表COMSPECし、OS2_SHELL環境変数を。同様に、DebianのSystem V rcおよびパッケージのインストール/削除スクリプトのbashismsの削除に関する議論は、1990年代にさかのぼります。

参考文献


2
「最終的に、DebianはAlmquistシェルにわずかな調整を加えなければなりませんでした。単純に深すぎて広く埋め込まれ、削除するには役に立たないいくつかの非POSIXシェル構成のサポートを追加しました。」—あなたの多くのリンクのどれがこれに関する情報を持っていますか?それはとても興味深いですね。:)
ワイルドカード

3
私見、パフォーマンスは人々に変化に同意してもらうための動機付けにすぎません。変更の最初の大きな理由は、bashが後方互換性を破り続けたことでした。スクリプトはbashのあるバージョンでは機能するが別のバージョンでは失敗するため(通常はOSのアップグレード後に発生するため)、私は個人的に少なくとも3回はbashの問題を修正しなければなりませんでした。Dashは、わずかに速いインタープリターではありません。また、動作の面でもはるかに安定しています。
スリーブマン

Schily Bourne Shellmanページのコメント(schilytools.sourceforge.net/bosh.htmlを参照が、人々がポータブルスクリプト(Bourne Shell features1989年からのみに依存する)の書き方を理解できるようにするのに適しているかどうかに興味があります。私がしたことは、古いBourne Shellにはなかったすべての機能強化について言及していました。ところで:私はまた、ダッシュのバシズムのリストを知りたいと思っています。
15

8

/ bin / bashではなく/ bin / shを指すシェバンを持つ理由はありますか?

はい。@Marcoの優れた答えは、このことをよく示しています。

私のシバンでは何を使うべきですか?

独自のスクリプトを作成するときは、テストした最も一般的なものにシバンを向ける必要があります。

私のシステム(shCentos 6.6)では、以下にシンボリックリンクされていbashます:

$ ls -l /bin/sh 
lrwxrwxrwx 1 root root 4 Dec  2  2014 /bin/sh -> bash

これは#!/bin/bash、スクリプトにバシムがないことを確認しない限り、常にシバンで使用することを意味します。

#!/bin/shあなたにシバンを設定することにより、スクリプトがのすべての実装で動作することを約束していますsh

これは、スクリプトがbashで動作すると言うよりもはるかに大きな約束です。

次にsh、システムが使用している実装に応じて正しく動作しないスクリプトの例を示します。

#!/bin/sh
n=1
a=$((++n))
echo $n

bashスクリプトを使用すると、印刷されます:

2

dashスクリプトを使用すると、印刷されます:

1

#!/bin/sh何を使用したいのですか?

  • スクリプトをチェックしますcheckbashisms-これはすべてのバシムを見つけるわけではないことに注意してください。上記のスクリプトでバシズムが見つかりませんでした
  • 別のsh実装を使用してスクリプトをテストします。私は通常、でテストしますがdash、一部のバシズムやダシムがまだすり抜けることができると予想しています。

Ubuntu wiki のDashAsBinShページには、多くの興味深い情報があります。


6
「独自のスクリプトを記述するときは、テストした最も一般的なものにシバンを向ける必要があります。...! 」 素晴らしい点。+1、そしてあなたは私が将来のために私のシバンを書く方法を再考させました。ありがとうございました!:)
ワイルドカード

2
さて、;のすべての実装では/bin/shありません。POSIX準拠のものだけです。
ブラックライトシャイニング

4

より強力で人間工学に基づいた言語のスクリプトの代わりにシェルスクリプトを記述する唯一の理由は、インストールされたソフトウェアの不明なセットを持つレガシーシステムへの移植性が他の要因よりも重要である場合です

/bin/shUnixと呼ばれるすべてのもので利用できる唯一のスクリプトインタープリタです。しかし、/bin/sh非常に多くのレガシーシステムでは、関連するユーティリティはPOSIX.1-1996の「シェルおよびユーティリティ」仕様に準拠していません。標準に準拠したツールは、オプションのアドオンであり、インストールされている/usr/xpg4場所またはそのような非自明な場所です。1 ポータブルサブセットシェル言語へのスクリプティングは、POSIXシェル言語へのスクリプティングよりも退屈でエラーが発生しやすくなります。(configureあなたが私を信じないなら、いつかAutoconfで生成されたスクリプトを読んでください。セットアップだけであなたを納得させることができます。)

ただし、他のスクリプトインタープリター(Bashなど)がインストールされていると想定できる場合は、より優れたスクリプト言語のインタープリターがインストールされていると想定できます。Perlは、例えば、あるより多くのバッシュがあるよりも利用可能である可能性が高いです。

したがって、スクリプトを記述しないでください。これが#! /bin/bashオプションである場合、より良い言語もオプションであるためです。

1たとえば、Solaris 10以前では、元のBourneシェルがとして出荷されていました/bin/sh。Solaris 11でksh93に更新されたことがわかりました。


3
システムを起動するスクリプトをどの言語で作成しますか?または、SOHOルーター内(限定された組み込みシステム)?またはAndroidで?これらすべての場合にシェルが使用可能になります。Perlではありません。

1
回答のSolaris関連部分について、いくつかの不正確さがあります。Solaris 10以前で/bin/sh POSIX.1-1996ではなく、実際にはPOSIX以前の構文の元のBourneシェルです。その#!/bin/shため、これらのリリースでスクリプトを実行するには非常に貧弱です。Solaris上の移植可能なスクリプトは#!/usr/xpg4/bin/sh、他のOSではあまり移植性がないものを使用します。最新のSolarisでは、最初に2011をリリースのOracle Solaris 11は、/bin/sh近代的でksh93、最近のPOSIX仕様に準拠し、かつは、多くの現代の拡張機能を持っていること。
jlliagre

1
@BinaryZebra:「A shell」が利用可能になります、はい。しかし、bashは必ずしもそのシェル(特にashbusyboxで提供されるほとんどのSOHOルーターが使用する)であるとは限らず、perlはbashより一般的に利用可能であるとzwolは正しいと思う傾向があります。
ベンフォークト

1
@BenVoigt私はこの文についてコメントしている「シェルスクリプトを書く唯一の理由」。いくつかのタスク(すべてではない)のためにシェルを必要とするいくつかのインスタンスがまだあります。それらは私の頭上からのいくつかの例でした。OTOH十分なメモリ(今日の標準ではほぼすべて)とPerl(またはPython、または...)をインストールするのに十分な電力を備えたシステムでは、非常に迅速かつ簡単です。ただし、特定のシェルを推奨していません。私のコメントのどこでそれを読みますか?

2
bash利用可能であれば、より良い言語であるため、bashコードを記述しないでください」という非常に意見が多く、事実に反する主張にはまったく反対します。また、@ sixtyfootersdudeが指摘しているように、スクリプトがPOSIXシェルで動作することをテストしていない限り、常に使用する必要があります。#!/bin/bash
ワイルドカード

0

実際に使用する必要があります

#! /bin/env sh

または

#! /bin/env bash

その方法で、そのシステムにインストールする方法でいずれかのシェルを呼び出します。

たとえば、シングルユーザーの再起動の場合)超安全にするにはsh、を使用しますbash


6
この答えthe advantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH. The disadvantage of #!/usr/bin/env python is that it will use whatever python executable appears first in the user's $PATH.これはおそらくにも適用shしてbash
ジュール

12
いいえ、#!/bin/envポータブルスクリプトでは何も使用しないでください。それが/bin/sh存在し、POSIX準拠の動作するシェルであると仮定することは完全に合理的です。一方、私のシステムにはがありません/bin/env
ブラックライトシャイニング

良い点も。
ジュール

1
@Blacklight Shining間違いなく、POSIX準拠のシェルをで想定するのは間違い/bin/shです。POSIXはこれを必要とせず、POSIX認定プラットフォームでPOSIX準拠の環境を実現するために他のルールを定義します。
ずんぐりと

4
/usr/bin/env...普遍的に利用できません
vonbrand
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.