Bash(バッシュ)はUnixシェルかつコマンド言語であり、GNUプロジェクトにおけるBourne Shellの自由ソフトウェアによる代替としてブライアン・フォックスによって作成された。Bashは1989年に初めてリリースされ、ほとんどのLinuxディストリビューションのデフォルトのログインシェルとして広く普及している。Windows 10におけるWindows Subsystem for Linuxでも利用可能である。

Bashはコマンドプロセッサであり、通常はアクションを発生させるコマンドをユーザーがタイプするテキストウィンドウで起動する。Bashはスクリプトと呼ばれるファイルからコマンドを読み込んで実行することも可能である。Bashはそれ以外の全てのUnixシェルと同様に、ファイル名のグロブ(ワイルドカードによるマッチング)、パイプ、ヒアドキュメント、コマンド置換、変数、そして条件テストや反復のための制御構造をサポートする。Bashの予約語や構文などの言語の基本的要素は全てBourne shellからコピーされており、ヒストリなどBourne shell以外の機能はC ShellやKornShellからコピーされている。BashはPOSIX準拠のシェルであるが、数多くの拡張がされている。

Bashという名前は Bourne-again shell(ボーン・アゲイン・シェル) の頭字語であり、Bashの置換対象であるBourne Shellと、現代アメリカのキリスト教において精神的な再生を意味する born again(ボーン・アゲイン)(新生)に引っ掛けた駄洒落である。

## 歴史

ブライアン・フォックスは1988年1月10日にBashのコーディングを開始したが、これは彼の前任開発者に進歩が見られなかったことにリチャード・ストールマンが不満を抱くようになってからのことである。ストールマンとフリーソフトウェア財団 (FSF) は、BSDやGNUのコードからビルドされた完全にフリーなシステムにとって既存のシェルスクリプトを実行できるフリーなシェルは戦略上非常に重要であると考えていたため、Bashは彼らが自ら創設した数少ないプロジェクトのうちの1つとなり、フォックスはFSFの従業員としてその作業を引き受けた。フォックスは1989年6月8日にBashのベータ版であるバージョン.99をリリースし、1992年中頃から彼がFSFから去る1994年中頃の間のある期間まで主要なメンテナであった。フォックスが去った後、彼の責務はもう一人の初期貢献者であるChet Rameyへと移された。

それ以降BashはLinuxユーザーの間で最も有名なシェルとなり、様々なLinuxディストリビューションのデフォルトインタラクティブシェルとなっている(ただしデフォルトのスクリプトシェルがAlmquist ShellであるLinuxディストリビューションもある)。BashはMicrosoft Windowsにも移植されてCygwinやMinGWの一部として配布されており、DJGPPプロジェクトによりDOSにも移植され、NetWareにも移植され、さらに様々な端末エミュレータを通じてAndroidにも移植されている。

2014年9月、UNIX/Linux・ネットワーク・テレコム専門家でありイギリスで働いているStéphane Chazelasは、プログラム内にセキュリティバグを発見した。このバグは最初9月24日に公開されてシェルショックと命名され、CVE-2014-6271, CVE-2014-6277およびCVE-2014-7169のナンバーが割り当てられた。Bashを使用したCGIスクリプトで任意コード実行が可能となり攻撃されやすくなるため、シェルショックは深刻なバグとみなされた。シェルショックは、Bashが環境変数を通じてサブシェルに関数定義を渡す方法と関係していた。

## 機能

Bashのコマンド構文は、Bourne shellのコマンド構文のスーパーセットである。構文の前処理においてBashと異なって解釈される振る舞いに偶然遭遇してしまったり、新しくBashに組み込まれたコマンドと同じ名前のシステムコマンドを起動しようとするBourne shellスクリプトを除いて、Bashは大量に存在するBourne shellスクリプトのほとんどを修正せずに実行可能である。Bashのコマンド構文には、コマンドライン編集、コマンド履歴、ディレクトリスタック、変数 `$RANDOM`や変数 `$PPID`、およびPOSIXのコマンド置換構文である`$(コマンド)`など、KornShellやC shellから引用したアイデアが含まれる。

ユーザーがインタラクティブコマンドシェルでタブキーを押した場合、Bashは途中までタイプされたプログラム名やファイル名などの様々な名前をマッチさせるコマンドライン補完を自動で行う。Bashのコマンドライン補完システムは大変融通が利きカスタマイズ可能であるため、特定のプログラムやタスク用の引数やファイル名を補完する関数とまとめてパッケージングされることが多い。

Bashの構文には、Bourne shellにはない拡張が多く存在する。Bashは他のプロセスを生成せずに整数演算ができる。この演算のためにBashは `((数式))` コマンドと `$((数式))` 変数構文を利用する。Bashの構文は入出力リダイレクトを単純化する。例えば、Bashでは `&>` 演算子を使用することで、標準出力と標準エラー出力を同時にリダイレクトすることができ、Bourne shellにおいてこれに相当するコマンドである `コマンド > file 2>&1` よりも簡単にタイプできる。Bashは`<(コマンド)`および`>(コマンド)`構文を使用することにより、プロセス置換をサポートする。この構文は、通常のリダイレクトではファイル名が記述される箇所にある`コマンド`の出力(または入力)を引数の代用とする(これは名前なしパイプをサポートするシステムならば `/proc/fd/` の名前なしパイプにより実装され、名前付きパイプが必要ならば一時的な名前付きパイプにより実装されている)。

`function` キーワードを使用する場合、Bashの関数宣言はBourne・Korn・POSIXスクリプトと互換性がない(KornShellでも `function` を使用する場合に同様の問題が起こる)が、BashはBourne shellやKornShellの関数宣言構文を受け入れるためPOSIX準拠である。これ以外にも違いがあるため、互換性確保を配慮せず書かれたBashのシェルスクリプトをBourneやKornShellのインタプリタで起動できることは滅多にないが、Linuxが普及するにつれて互換性確保を配慮せずに書くことは少なくなっている。ただしPOSIXモードにおいては、Bashはより密接にPOSIXに準拠している。

Bashはヒアドキュメントをサポートする。Bashはバージョン2.05bより、`<<<`演算子を使った「ヒア文字列」から標準入力へのリダイレクトが可能である。

Bash3.0ではPerl言語を思い起こさせる構文を使用した、シェル組み込みの正規表現をサポートする。

Bash4.0では連想配列のサポートが導入された。

### ブレース展開

ブレース展開はオルターネイションとも呼ばれ、C shellから取り入れた機能である。ブレース展開は取り得る組み合わせのセットを生成する。生成された結果はファイルとして存在する必要はない。展開された各文字列結果はソートされておらず、保存された順に左から右へと並んでいる:

Bourne shellではBashと同じ出力を返さないため、ユーザーは移植するためのシェルスクリプトでブレース展開を使うべきではない。

ブレース展開がワイルドカードと組み合わされた場合、最初に括弧が展開されてから通常通りワイルドカードが置換される。したがって、カレントディレクトリにある拡張子が `.jpg` または `.jpeg` または `.png` のファイル群を獲得するには以下のようにする:

ブレース展開は取り得る全ての組み合わせだけではなく、連続した範囲に対して適用することも可能である。範囲は2つの整数や文字の間を、2つのドットで区切って指定する。Bashの新しいバージョンでは、範囲の終点を指定する2つ目の整数の後にさらに2つのドットと3つ目の整数を指定することで、範囲の増分を指定することも可能である。

ブレース展開を変数展開と組み合わせると、ブレース展開が先に行われ変数展開がその後に行われてしまうため、場合によっては`eval`ビルトインが必要になる可能性もある:

### 起動スクリプト

Bashは起動の際、様々なドットファイルのコマンドを実行する。Bashが使用する初期化ファイルは、実行権限が与えられてかつ `#!/bin/bash` のようなシバンが記述されたBashのシェルスクリプトコマンドと似てはいるものの、実行権限とインタプリタディレクティブのどちらも必要ない。

#### 起動ファイルの実行順序

| 条件 | 順序 |
| --- | --- |
| インタラクティブな非ログインシェルとして起動 | Bashは`/bash.bashrc`を読み込んで実行してから、(存在する場合)`~/.bashrc`を読み込んで実行する。これは `--norc` オプションを使うことで禁止することができる。`--rcfile ファイル`オプションにより、`~/.bashrc` の代わりに `ファイル` からコマンドを読み込んで実行するようBashに強制させることができる。 |
| インタラクティブなログインシェルとして起動 | Bashは(存在する場合)`/etc/profile`(ファイル名を`/etc/bash.bashrc`と改名されることが多い)を読み込み実行する。このファイルを読み込んだ後、`~/.bash_profile`、`~/.bash_login`、および`~/.profile`をこの順番で調べ、存在しかつ読み込めるもののうち最初のものを読み込んで実行する。 |
| ログインシェルを終了した場合 | Bashは(存在する場合)`~/.bash_logout`を読み込んで実行する。 |

#### Bourne shellやC shellの起動シーケンスとの比較

Bashの各要素はBourne shellやC shellからの派生である。このため、制限付きながら起動ファイルをBourne shellと共用でき、さらにC shellユーザーには馴染みのあるいくつかの起動シーケンスを提供する。

| 項目 | 違い |
| --- | --- |
| 継承可能な環境変数の設定 | Bourne shellはサブプロセス化されてから継承する環境変数を設定するため、ログイン時に`~/.profile`を使用する。Bashでも、Bash固有の`~/.bash_profile`や`~/.bash_login`に以下の行を記述して、それらから明示的に`~/.profile`を実行することでBourne shellと互換性を保つことが可能となる。Bash固有の構文を`~/.profile`に記述しないことで、Bourne shellとの後方互換性を保つことが可能となる。 ``` . ~/.profile ``` |
| エイリアスと関数 | C shell由来のエイリアスという機能が存在するが、その大部分を置き換えるBourne shell由来の関数という機能はエイリアスよりも一般的である。これら2つの機能は通常ログインシェルから継承することはできず、ログインシェルによって生み出されたサブシェル毎に再定義する必要があった。この問題の対処に利用可能な環境変数 `ENV` が存在するが、C shellとBashではこの問題に直接的を絞ったサブシェル毎の起動ファイルをサポートする。Bashでは `~/.bashrc` がインタラクティブサブシェルのために呼び出される。`~/.bashrc` にあるユーザー定義関数がログインシェルでも必要な場合、以下の行を `~/.bash_login` へ必要な環境変数の設定後に記述する: ``` . ~/.bashrc ``` |
| ログイン時のみやログアウト時のみに実行するコマンド | C shellは最初のログイン時のみに実行されるタスクのための `~/.login` ファイルをサポートする。このようなタスクにはシステムのロード、ディスクステータス、電子メールが来たかの有無などの表示や、ログイン時間のロギングなどがある。Bourne shellは `~/.profile` でこのファイルを模倣できるが、ファイル名は事前に定義されていない。C shellモデルに似たセマンティクスを実現するため、`~/.bash_profile` では環境設定や関数設定の後に以下の様に記述できる: ``` . ~/.bash_login ```  同様に、C shellはログインシェルを終了した場合のみに起動される `~/.logout` ファイルを持つ。Bashでこれに相当するのは `~/.bash_logout` であり、特殊な設定は必要ない。Bourne shellでは、似たような効果を得るためには組み込みコマンド `trap` を使用できる。 |

##### レガシー互換なBash起動例

以下の `~/.bash_profile` コードはBourne shellと互換性があり、`~/.bashrc` と `~/.bash_login` に対してC shellと似たセマンティクスを提供する。`[ -r ファイル ]`は ファイル が存在し読み込める場合`0`を、そうでない場合は`1`を返す。返り値が0の場合 `&&` の後の部分が評価される。

#### Bash起動におけるオペレーティングシステムの問題

UNIXやLinuxのバージョンの中には、`/etc` ディレクトリ配下にBashシステム起動スクリプトが存在するものもある。Bashはこれらのスクリプトを、Bashの通常の初期化の一部として呼び出すが、それ以外の起動ファイルをBash起動シーケンスの記述と異なる順序で読み込むこんでしまう可能性がある。さらにシステムが新しいユーザーアカウントに設定を提供するスケルトンファイルのように、ルート・ユーザーのファイル内におけるデフォルトの内容に問題がある可能性もある。ウィンドウマネージャの起動前にユーザーがBash起動スクリプトで自身の環境変数を準備しようとすると、X Window Systemの起動スクリプトにより予想外の問題が発生する可能性がある。これらの問題は、`~/.profile` を読み込むために `~/.xsession` や `~/.xprofile` ファイルを使う場合に発生する可能性が高い。これらのファイルはxtermや GNOME 端末などの、ウィンドウマネージャから生み出されたBashシェルウインドウが必要とする環境変数を提供する。

### 移植性

`--posix`オプションを付けてBashを呼び出したり、スクリプトに`set -o posix`を記述すると、BashはPOSIX 1003.2 standardに非常に良く準拠する。伝統的なBourne ShellにはないがBashには搭載されている機能は以下である:

- 特定の拡張呼び出しオプション
- `$(コマンド)` 記法を使ったコマンド代替(ただしこの機能はPOSIX1003.2規格の一部)
- ブレイス展開
- 特定の配列演算と連想配列
- テストコンストラクトを拡張する二重括弧
- 二重括弧の算術評価コンストラクト
- 特定の文字列操作(ただし一部の機能はPOSIX1003.2規格の一部)
- プロセス代替
- 正規表現マッチング演算子
- Bash特有の組み込み機能
- コプロセス

bashism(バシズム) とは、Bash以外のUnixシェルでは適切に動作しないBashコードの部分を指す。

### キーボードショートカット

Bashはデフォルトの (Emacs) キーバインディングを利用して編集するためのコマンドライン用キーボードショートカットを提供するために、Readlineを利用する。`set -o vi`を起動すればViバインディングが利用可能となる。

### プロセス管理

Bashにはコマンドに対する実行モードとして、バッチモードと並行実行モードの2つがある。

バッチモードつまりコマンドを逐次的に実行するためには、コマンドを「`;`」文字や別の行で分割する必要がある:

上記の例では、`コマンド1` が完了した後で `コマンド2` が実行される。

`コマンド1` と `コマンド2` を並行実行するには、以下の方法で実行する必要がある:

上記の例では、`コマンド1` がバックグラウンド(シンボル `&`)で実行され、フォアグラウンドで `コマンド2` を実行するシェルへとすぐに制御が戻される。

プロセスはフォアグラウンド状態とバックグラウンド状態だけでなく、停止状態にすることも可能である。プロセスがフォアグラウンドで実行されていれば、これは`Ctrl`+`z`をタイプすることで行える。バックグラウンドプロセスおよび停止されたプロセスの全てを一覧するには`jobs`を起動することで行える:

上記の出力では、括弧内の数はジョブIDを示している。プラス記号は `bg` や `fg` に対応するデフォルトプロセスを指し示す。RunningおよびStoppedという表示は、プロセス状態を指し示す。最後の文字列はプロセスを開始したコマンドである。

プロセスの状態は様々なコマンドを使うことで変更できる。`fg` コマンドはプロセスをフォアグラウンドにして、`bg` は停止されたプロセスをバックグラウンドで実行するよう設定する。`bg` と `fg` は最初の引数に処理するプロセスを指定するジョブIDを渡すことができる。引数がない場合、`jobs` の出力でプラス記号が付いたデフォルトプロセスに対して処理が行われる。プロセスにシグナルを送って中断するためには、`kill`コマンドを使うことができる。ジョブIDはパーセント記号 「`%`」の後に指定する必要がある:

### 条件付き実行

Bashは先行するコマンドにより設定された終了コードに応じてコマンドを実行する、「条件付き実行」コマンド区切り文字を提供する。以下にその例を示す:

`./何かのコマンド` は、`cd` コマンドが「成功」した(終了ステータスとして `0` を返した)場合のみ実行され、`echo` コマンドは `cd` か `./何かのコマンド` コマンドのどちらかがエラーを返した(終了ステータスが `0` 以外を返した)場合のみ実行される。

全てのコマンドに対して、終了ステータスは特殊な変数である `$?` に保存される。Bashは条件コマンド評価の形式として、`if 条件 ; then 条件を満たす場合の処理 ; else 条件を満たさない場合の処理 ; fi` や `case $変数 in パターン1) 処理1 ;; パターン2) 処理2 ;; esac` もサポートする。

### バグ報告

`bashbug` と呼ばれる外部コマンドはBashのバグを報告する。このコマンドが呼び出されると、フォームが入力された状態でユーザーのデフォルトエディタが表示される。このフォームはBashのメンテナ(またはオプションでそれ以外のメールアドレス)にメールされる。