HOWTO · Linux

Sh と Bash の違い

このチュートリアルでは、シェルとは何かを説明し、現在使用されているシェルを把握し、使用可能なすべてのシェルのリストと、sh と bash の違いを確認します。

このページの内容

シェルはコマンドインタープリターです。端末で実行中のシェルプロセスを特定するには、そのプロセスを調べます。アカウントに設定されたシェルを確認するには、アカウント情報を調べます。システムの /etc/shells ファイルには、有効なログインシェルとして認められているシェルが記載されています。移植性の高い POSIX 形式のスクリプトには sh を使い、追加機能が必要な場合は Bash を使います。

シェルとは何ですか?

シェルはコマンドを読み取り、オペレーティングシステムによる実行を調整します。対話型シェルは端末からコマンドを受け取ります。一方、スクリプトファイルには、インタープリターに実行させるコマンドを記述できます。Linux システムには、Bash、Dash、その他の POSIX 互換実装など、複数のシェルが用意されている場合があります。現在使用中のシェル、アカウントに設定されたシェル、個々のスクリプトを解釈するインタープリターは、互いに関係していますが、それぞれ別のものです。

現在のシェルを確認する方法

Linux で現在実行中のシェルプロセスを調べるには、ps -p "$$" -o comm= を実行します。$$ パラメーターは現在のシェルのプロセス ID に展開され、ps はそのプロセスのコマンド名を表示します。これで実行中のプロセスを特定できますが、ログイン時にアカウントで起動するシェルが分かるとは限りません。別のシェル、端末、またはスクリプトから起動されたプロセスは、設定済みのログインシェルと異なることがあります。

/etc/passwd のアカウント情報には、実行中のプロセスではなく、設定されたログインシェルが記録されています。現在のアカウントについては、getent passwd "$USER" を実行すると、システムのアカウントデータベースを検索してレコードを表示します。コロンで区切られた最後のフィールドが、設定されたシェルのパスです。これは現在実行中のシェルプロセスと異なる場合があります。システムのアカウントサービスや環境設定もセッションの起動方法に影響することがあるため、「今何が実行されているか」を知りたい場合はプロセスを調べてください。

利用可能なシェルを確認する方法

たとえば cat /etc/shells を実行して /etc/shells を読み取ると、システムで有効なログインシェルとして登録されているパスを確認できます。内容はシステムによって異なります。このファイルは、マシンにインストールされているすべてのシェルバイナリを網羅した一覧ではありません。インストール済みのプログラムが記載されていないこともあれば、記載されたパスがシンボリックリンクで管理されていることもあります。ログインシェルとして使用できるかどうかの確認に使い、記載されたプログラムがすべて現在実行中であることや、インストール済みのシェルがすべて載っていることの証明には使わないでください。

sh コマンドとその使い方

sh は、コマンド言語インタープリターの伝統的な名称です。移植性を重視したシェルスクリプトで sh と言う場合、通常は互換性のある実装で実行できるよう、POSIX シェル言語で記述することを指します。POSIX は共通の動作を定めていますが、/bin/sh はパスであり、その実装はオペレーティングシステムやディストリビューションによって異なります。Dash、Bash、その他のシェルに解決される場合があります。システムを確認せずに、特定の実装だと決めつけないでください。

スクリプトの先頭行はシバンと呼ばれ、スクリプトを実行可能ファイルとして起動したときに使うインタープリターを指定します。たとえば #!/bin/sh は /bin/sh にあるインタープリターを要求しますが、そのパスがどの実装を選ぶかまでは保証しません。同じスクリプトをコマンドラインから sh に明示的に渡して実行することもできます。sh 用のスクリプトでは Bash 専用の構文を避け、移植性を重視する場合は POSIX で定義された構文を使ってください。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

printf 'Hello, shell!\n'
Hello, shell!

この自己完結型のコマンドは、提供された実行時証拠に記録されている出力を表示します。

Bash の使い方

Bash(Bourne Again SHell)は広く使われているシェルで、配列、[[ ... ]] によるテスト、プロセス置換など、移植性を重視した sh スクリプトにはない機能を備えています。これらの拡張機能を使うスクリプトでは、たとえば #!/bin/bash のようにシバンで Bash を指定し、Bash で実行してください。Linux では Bash が一般的ですが、すべての Linux システムで既定のシェルとは限りません。

Bash では POSIX モードも有効にできます。bash --posix を指定して Bash を起動するか、Bash スクリプト内で set -o posix を実行します。これにより Bash の動作は POSIX の要件に近づきますが、Bash が別の sh 実装に変わるわけでも、Bash 専用のスクリプトがすべて移植可能になるわけでもありません。移植性が重要なら、POSIX シェル言語で記述し、対象システムのシェルでテストしてください。