web-dev-qa-db-ja.com

Shとbashの違い

シェルプログラムを書くとき、私たちはしばしば/bin/sh/bin/bashを使います。私は通常bashを使いますが、両者の違いがわかりません。

bashshの主な違いは何ですか?

bashおよびshでプログラミングするときに注意する必要があることは何ですか?

1068
Weiwei Yang

Shとは何ですか

shまたはシェルコマンド言語)は、_(POSIX standard 。)で記述されているプログラミング言語です(ksh88dash、...)。bashshの実装と見なすこともできます(下記参照)。

shは実装ではなく仕様であるため、/bin/shはほとんどのPOSIXシステム上の実際の実装へのシンボリックリンク(またはハードリンク)です。

Bashとは

bashshと互換性のある実装として始まりましたが(数年前までにPOSIX標準より前になりましたが)、それは多くの拡張を獲得しました。これらの拡張機能の多くは、有効なPOSIXシェルスクリプトの動作を変更する可能性があるため、bashはそれ自体では有効なPOSIXシェルではありません。むしろ、それはPOSIXシェル言語の方言です。

bash--posixスイッチをサポートします。これにより、POSIX準拠が強化されます。 shとして呼び出された場合もPOSIXを模倣しようとします。

sh = bash?

長い間、/bin/shはほとんどのGNU/Linuxシステムで/bin/bashを指していました。その結果、両者の違いを無視しても安全になりました。しかし、それは最近変わり始めました。

/bin/sh/bin/bashを指していない(および/bin/bashが存在しない場合もある)システムの一般的な例は次のとおりです。

  1. デフォルトのshdashにシンボリックリンクする、最新のDebianおよびUbuntuシステム。
  2. Busybox 、これは通常Linuxシステムの起動時にinitramfsの一部として実行されます。これはashシェル実装を使用します。
  3. BSD、そして一般的にはLinux以外のシステム。 OpenBSDはKornシェルの子孫であるpdkshを使います。 FreeBSDのshは、オリジナルのUNIX Bourne Shellの子孫です。 Solarisには独自のshがあり、長い間POSIXに準拠していませんでした。無料の実装は Heirloom project )から入手できます。

あなたのシステムで/bin/shが指しているものをどうやって見つけることができますか?

厄介なのは、/bin/shがシンボリックリンクまたはハードリンクになる可能性があることです。もしそれがシンボリックリンクなら、 portable それを解決する方法は:

% file -h /bin/sh
/bin/sh: symbolic link to bash

ハードリンクの場合は、試してください

% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash

実際、-Lフラグはシンボリックリンクとハードリンクの両方をカバーしますが、この方法の欠点は移植性がないことです - POSIX -samefileオプションをサポートするためにfindを必要としません、両方とも GNU findFreeBSDのfind に対応しています。

シェバン線

最終的に、«Shebang»の行を書いてどちらを使うか決めるのはあなた次第です。

例えば。

#!/bin/sh

shを使用します(そして、それが指し示すものは何でも)。

#!/bin/bash

利用可能であれば/bin/bashを使用します(利用できない場合はエラーメッセージを表示して失敗します)。もちろん、他の実装を指定することもできます。

#!/bin/dash

どちらを使うか

私自身のスクリプトでは、以下の理由からshを好みます。

  • それは標準化されています
  • ずっと簡単で習得が簡単です。
  • pOSIXシステム間で移植性があります - たとえそれらがbashを持っていなかったとしても、それらはshを持っている必要があります。

bashを使うことにも利点があります。その機能はプログラミングをより便利にし、他の現代のプログラミング言語のプログラミングに似ています。これらはスコープ付きローカル変数や配列のようなものを含みます。プレーンshは非常にミニマルなプログラミング言語です。

968
Roman Cheplyaka

shhttp://man.cx/sh
bashhttp://man.cx/bash

TL; DR bashは、より洗練された構文とより多くの機能を持つshのスーパーセットです。現代のプラットフォームでは非常に遍在するため、ほとんどすべての場合でbash Shebangラインを使用するのが安全です。

注意:環境によっては、shisbashとなります。 sh --versionを確認してください。

107
Rein Henrichs

この質問は、shを使おうとし、それがbashと同じ動作をしないことに驚いている人々のための規範としてしばしばノミネートされています。これはよくある誤解と落とし穴の概要です。

最初に、あなたは何を期待すべきか理解するべきです。

  • sh scriptnameを付けてスクリプトを実行する場合、またはscriptnameを指定してスクリプトを実行し、 Shebang 行に#!/bin/shがある場合は、POSIXのshの動作が期待できます。
  • スクリプトをbash scriptnameを付けて実行するか、scriptnameを指定して実行し、Shebang行に#!/bin/bash(またはそれに相当するもの)を含めると、Bashの動作が期待できます。

正しいShebangを持っていて、スクリプト名だけを(おそらく相対パスまたは絶対パスで)入力してスクリプトを実行することが、一般的に推奨される解決策です。正しいShebangに加えて、これにはスクリプトファイルに実行権限(chmod a+x scriptname)が必要です。

それで、それらは実際にどう違うのでしょうか?

Bashリファレンスマニュアルには 違いを列挙しようとするセクション がありますが、一般的な混乱の原因には次のものがあります。

  • [[shでは使用できません(よりぎこちなく制限されている[のみ)。
  • shは配列を持ちません。
  • localsourcefunction、およびselectなどの一部のBashキーワードは、shに移植できません。 (いくつかのshの実装は例えばlocalをサポートします。)
  • Bashには、$'string\nwith\tC\aescapes'や3つの引数を持つfor((i=0;i<=3;i++))ループ、+=の増分代入など、多くのCスタイルの構文拡張があります。
  • Bashは<<<'here strings'をサポートしています。
  • Bashは*.{png,jpg}{0..12}のブレース展開をしています。
  • ~はBashでのみ$HOMEを参照します(より一般的には~usernameusernameのホームディレクトリを指します)。これはPOSIXにありますが、いくつかのPOSIX以前の/bin/shの実装に欠けているかもしれません。
  • Bashは<(cmd)>(cmd)でプロセスを置き換えています。
  • Bashには、&|2>&1 |&>> ... 2>&1のようなCshスタイルの便利なリダイレクトエイリアスがあります。
  • Bashは<>リダイレクションによるコプロセスをサポートしています。
  • Bashは、${substring:1:2}${variable/pattern/replacement}、大文字小文字変換などの拡張された非標準のパラメーター展開の豊富なセットを備えています。
  • Bashはシェル演算の機能を大幅に拡張しました(ただし浮動小数点サポートはまだありません)。
  • オプションの動作を有効または無効にし、シェルの内部状態を公開するための、多数の、多くのBash専用拡張。
  • 対話的に使用するための多くの便利な機能がありますが、スクリプトの動作には影響しません。

覚えておいて、これは要約されたリストです。完全なスクープについてはリファレンスマニュアルを、そして多くの良い回避策については http://mywiki.wooledge.org/Bashism を参照してください。そして/または http://shellcheck.net/ を試してみてください。これは多くのBashのみの機能を警告します。

一般的なエラーとしては、#!/bin/bash Shebang行がありますが、それでもsh scriptnameを使用して実際にスクリプトを実行します。これは基本的にBashのみの機能を無効にするので、構文エラーが発生します。配列を使用しようとしたため。

残念ながら、shとして呼び出されたときにBashはこれらの構成要素を使用しようとしても警告しません。 all Bashのみの機能を完全に無効にするわけでもないので、Bashをshとして呼び出して実行しても、スクリプトが ash に適切に移植可能かどうかを確認するのに適しません。 dash /POSIX sh または He​​irloom sh のような変種

53
tripleee

UNIX.COM から投稿

シェルの機能

以下の表は、シェルを他のシェルよりも選択できるようにすると思われるほとんどの機能をまとめたものです。これは明確なリストになることを意図したものではなく、可能なすべてのシェルのすべての可能な機能をすべて含むわけでもありません。機能は、オペレーティングシステムに同梱されているバージョンの場合、または標準ディストリビューションから直接コンパイルされたものとして入手可能な場合にのみ、シェル内にあると見なされます。特に、以下に指定されているCシェルはSUNOS 4 *で利用可能なものです。かなりの数のベンダが代わりにtcshまたは独自の拡張Cシェルを出荷しています。

コード:

                                     sh   csh  ksh  bash tcsh zsh  rc   es
Job control                          N    Y    Y    Y    Y    Y    N    N
Aliases                              N    Y    Y    Y    Y    Y    N    N
Shell functions                      Y(1) N    Y    Y    N    Y    Y    Y
"Sensible" Input/Output redirection  Y    N    Y    Y    N    Y    Y    Y
Directory stack                      N    Y    Y    Y    Y    Y    F    F
Command history                      N    Y    Y    Y    Y    Y    L    L
Command line editing                 N    N    Y    Y    Y    Y    L    L
Vi Command line editing              N    N    Y    Y    Y(3) Y    L    L
Emacs Command line editing           N    N    Y    Y    Y    Y    L    L
Rebindable Command line editing      N    N    N    Y    Y    Y    L    L
User name look up                    N    Y    Y    Y    Y    Y    L    L
Login/Logout watching                N    N    N    N    Y    Y    F    F
Filename completion                  N    Y(1) Y    Y    Y    Y    L    L
Username completion                  N    Y(2) Y    Y    Y    Y    L    L
Hostname completion                  N    Y(2) Y    Y    Y    Y    L    L
History completion                   N    N    N    Y    Y    Y    L    L
Fully programmable Completion        N    N    N    N    Y    Y    N    N
Mh Mailbox completion                N    N    N    N(4) N(6) N(6) N    N
Co Processes                         N    N    Y    N    N    Y    N    N
Builtin artithmetic evaluation       N    Y    Y    Y    Y    Y    N    N
Can follow symbolic links invisibly  N    N    Y    Y    Y    Y    N    N
Periodic command execution           N    N    N    N    Y    Y    N    N
Custom Prompt (easily)               N    N    Y    Y    Y    Y    Y    Y
Sun Keyboard Hack                    N    N    N    N    N    Y    N    N
Spelling Correction                  N    N    N    N    Y    Y    N    N
Process Substitution                 N    N    N    Y(2) N    Y    Y    Y
Underlying Syntax                    sh   csh  sh   sh   csh  sh   rc   rc
Freely Available                     N    N    N(5) Y    Y    Y    Y    Y
Checks Mailbox                       N    Y    Y    Y    Y    Y    F    F
Tty Sanity Checking                  N    N    N    N    Y    Y    N    N
Can cope with large argument lists   Y    N    Y    Y    Y    Y    Y    Y
Has non-interactive startup file     N    Y    Y(7) Y(7) Y    Y    N    N
Has non-login startup file           N    Y    Y(7) Y    Y    Y    N    N
Can avoid user startup files         N    Y    N    Y    N    Y    Y    Y
Can specify startup file             N    N    Y    Y    N    N    N    N
Low level command redefinition       N    N    N    N    N    N    N    Y
Has anonymous functions              N    N    N    N    N    N    Y    Y
List Variables                       N    Y    Y    N    Y    Y    Y    Y
Full signal trap handling            Y    N    Y    Y    N    Y    Y    Y
File no clobber ability              N    Y    Y    Y    Y    Y    N    F
Local variables                      N    N    Y    Y    N    Y    Y    Y
Lexically scoped variables           N    N    N    N    N    N    N    Y
Exceptions                           N    N    N    N    N    N    N    Y

上の表へのキー。

Yこのシェルを使用して機能を実行できます。

N機能がシェルに存在しません。

F機能は、シェル関数メカニズムを使用してのみ実行できます。

Lこの機能を有効にするには、readlineライブラリをシェルにリンクする必要があります。

上の表に対する注意事項

1. This feature was not in the original version, but has since become
   almost standard.
2. This feature is fairly new and so is often not found on many
   versions of the Shell, it is gradually making its way into
   standard distribution.
3. The Vi emulation of this Shell is thought by many to be
   incomplete.
4. This feature is not standard but unofficial patches exist to
   perform this.
5. A version called 'pdksh' is freely available, but does not have
   the full functionality of the AT&T version.
6. This can be done via the shells programmable completion mechanism.
7. Only by specifying a file via the ENV environment variable.
47
SriniV

シェル は、オペレーティングシステムのサービスにアクセスするためのユーザーとOS間のインタフェースです。 GUIでもCLIでもかまいません(コマンドラインインターフェイス)。

sh (Bourne sh ell)は、Unix/Unixライクなオペレーティングシステム用のシェルコマンドラインインタプリタです。それはいくつかの組み込みコマンドを提供します。スクリプト言語では、インタプリタを#!/bin/shと表しています。それはbash(free/open)、kash(freeではない)のような他のシェルによって最も広くサポートされているものでした。

Bash _ b _ ourne a gain s hell)は、Bourneシェルに代わるシェルです。 bashはshのスーパーセットです。 bashはshをサポートしています。 POSIXは、POSIX準拠システムの動作方法を定義した一連の標準です。 Bashは実際にはPOSIX準拠のシェルではありません。スクリプト言語では、インタプリタを#!/bin/bashとして表します。

アナロジー:

  • シェルは、インターフェース、仕様、またはAPIのようなものです。
  • shは、Shellインタフェースを実装するクラスです。
  • Bashはshのサブクラスです。

enter image description here

33
Premraj

ターミナル

  • ウィンドウを起動するプログラム
  • xterm、rxvt、konsole、kvt、gnome-terminal、nxterm、およびeterm。

シェル

  • 端末で動作するプログラムです
  • シェルはコマンドインタプリタでもあり、プログラミング言語でもあります。
  • シェルは単にコマンドを実行するマクロプロセッサです。
  • マクロプロセッサとは、テキストや記号を拡大してより大きな表現を作成する機能を意味します。

SH対BASH

SH

  • (シェル)
  • 特定のシェルです
  • コマンドインタプリタとプログラミング言語
  • BASHの前身

BASH

  • (ボーンアゲインシェル)
  • 特定のシェルです
  • コマンドインタプリタとプログラミング言語
  • 機能性以上のものがあります
  • SHの後継者
  • BASHがデフォルトのシェルです

参考資料:

シェルgnu.org:

基本的には、コマンドを実行するシェルは単にマクロプロセッサですです。 マクロプロセッサとは、テキストや記号を展開してより大きな表現を作成する機能を意味します。

Unix Shellはコマンドインタプリタでもプログラミング言語でもあります。コマンドインタプリタとして、Shellは豊富なGNUユーティリティへのユーザインタフェースを提供します。プログラミング言語の機能により、これらのユーティリティを組み合わせることができます。コマンドを含むファイルを作成して、それ自体をコマンドにすることができます。これらの新しいコマンドは、/ binなどのディレクトリ内のシステムコマンドと同じステータスになり、ユーザーまたはグループが共通のタスクを自動化するためのカスタム環境を確立できるようになります。

シェルは対話的にも非対話的にも使用できます。インタラクティブモードでは、キーボードからの入力を受け付けます。非対話的に実行する場合、シェルはファイルから読み込んだコマンドを実行します。

シェルでは、同期的および非同期的にGNUコマンドを実行できます。シェルは同期コマンドが完了するのを待ってからさらに入力を受け入れます。非同期コマンドは、シェルが追加のコマンドを読み取って実行している間、シェルと並行して実行を続けます。リダイレクション構成要素は、それらのコマンドの入力と出力のきめ細かい制御を可能にします。さらに、シェルはコマンドの環境の内容を制御できます。

シェルはまた、別のユーティリティを介して取得することが不可能または不便な機能を実装する少数の組み込みコマンド(組み込みコマンド)を提供しますたとえば、cd、break、continue、およびexecはシェルの外部では実装できません _はシェル自体を直接操作するためです。 history、getopts、kill、またはpwdなどの組み込みコマンドは、別々のユーティリティに実装することもできますが、組み込みコマンドとして使用するほうが便利です。以降のセクションでは、すべてのShell組み込みコマンドについて説明します。

コマンドの実行は必須ですが、シェルの力(および複雑さ)の大部分は組み込みプログラミング言語によるものです他の高級言語と同様に、シェルには変数、フロー制御構造、引用符、および関数が用意されています。 。

シェルは、プログラミング言語を強化するのではなく、対話的な使用に特化した機能を提供しています。これらのインタラクティブ機能には、ジョブ制御、コマンドライン編集、コマンド履歴、エイリアスなどがあります。このマニュアルでは、これらの各機能について説明しています。

BASHgnu.org:

BashはGNUオペレーティングシステム用のシェル、またはコマンド言語インタプリタです。この名前は「Bourne-Again Shell」の頭字語で、現在のUnix Shell shの直接の祖先であるStephen Bourneの作者であり、これはUNIXのSeventh Edition Bell Labs Researchバージョンに登場しました。

Bashはshとほぼ互換性があり、Korn Shell kshおよびC Shell cshの便利な機能が組み込まれています。これは、IEEE POSIX仕様(IEEE規格1003.1)のIEEE POSIXシェルおよびツール部分の準拠実装であることを意図しています。対話的な使用とプログラミングの使用の両方に対して、shよりも機能が改善されています。

GNUオペレーティングシステムは、cshのバージョンを含む他のシェルを提供しますが、Bashはデフォルトのシェルですです。他のGNUソフトウェアと同様に、Bashはかなり移植性があります。現在、ほぼすべてのバージョンのUnixおよびその他のいくつかのオペレーティングシステムで動作します。MS-DOS、OS/2、およびWindowsプラットフォーム用に、独立してサポートされているポートがあります。

22

他の回答では、一般的にBashとPOSIXシェル標準との違いを指摘しました。ただし、移植可能なシェルスクリプトを作成してBash構文に慣れている場合は、典型的な概念とそれに対応する純粋なPOSIXソリューションのリストが非常に便利です。そのようなリストは、UbuntuがデフォルトのシステムシェルとしてBashからDashに切り替えたときにコンパイルされており、ここで見つけることができます: https://wiki.ubuntu.com/DashAsBinSh

さらに、 checkbashisms と呼ばれる素晴らしいツールがあります。これはあなたのスクリプトの中のbashismsをチェックし、あなたのスクリプトが移植可能であることを確かめたいときに役に立ちます。

14

/bin/sh/bin/bashと同じプログラムを起動してもしなくてもかまいません。

sh 少なくとも の機能 POSIXに必須 をサポートします(正しい実装を前提としています)。それは同様に拡張をサポートするかもしれません。

bash、 "Bourne Again Shell"は、shに必要な機能とbash固有の拡張機能を実装しています。拡張機能の完全なセットはここで説明するには長すぎます、そしてそれは新しいリリースで異なります。違いはbashのマニュアルに文書化されています。 info bashと入力して「Bashの機能」セクション(現在のバージョンのセクション6)を読むか、 現在のドキュメントはオンライン を読んでください。

3
Keith Thompson

bashとshは2つの異なるシェルです。基本的にbashはshであり、より多くの機能とより優れた構文を持っています。ほとんどのコマンドは同じように動作しますが、違います。bash(bash)は、利用可能な(まだ最も一般的に使用されている)Unixシェルの1つです。 Bashは "Bourne Again Shell"の略で、オリジナルのBourne Shell(sh)の置き換え/改良です。

BashスクリプトはBash専用のスクリプトですが、シェルスクリプトはあらゆるシェルでのスクリプトです。しかし実際には、問題のシェルがBashではない場合を除き、 "シェルスクリプト"と "bashスクリプト"は同じ意味で使用されることがよくあります。

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

0
Gopika BG