見出し画像

#!/bin/sh と #!/bin/bash の意味

#!から始まるおまじないの意味

#!/bin/shや#!/bin/bashなどの#!から始まるものは Shebang(シバンまたはシェバン)と呼ぶ。(※この文章の中ではシェバンと呼ぶことにする)シェバンのやっていることはファイルを実行するためのインタプリタのパスを指定すること

インタプリタは高級言語から機械語へ翻訳しながら同時に少しずつ実行していくプログラムのこと。また名前の由来は Hash(#) と Bang(!) をくっつけた HashBang の省略形。

本題

前置きから#!/bin/shと#!/bin/bashの意味の違いはインタプリタのパスの違いということがわかる。ではインタプリタのパスが違うことで、具体的にどう違いが現れるのか。 実は#!/bin/shはbashを指すシンボリックリンクで、#!/bin/bashは普通にbashを実行するために必要なシェバンである。シンボリックリンクとは

オペレーティングシステム(OS)のファイルシステムの機能の一つで、特定のファイルやディレクトリを指し示す別のファイルを作成し、それを通じて本体を参照できるようにする仕組み。

シンボリックリンク(ソフトリンク)とは - 意味をわかりやすく - IT⽤語辞典 e-Words

である。シンボリックリンクになっている理由は、bash は sh の機能を引き継いで、機能を拡張したものだから。ただ sh と完全互換ではないので、bash のみに存在する非互換機能(Bashismと呼ぶ)を意図せず sh で実行しようとするとエラーになる(正確には実行されずスキップされる)。リンク先を確かめるには

ls -l /bin/sh

とすれば良い。環境によるが例えば

lrwxrwxrwx. 1 root root 4 12 11:09 /bin/sh -> bash

となっていれば/bin/shはbashへのシンボリックリンクとなっている。また「sh でbashを実行しようとするとエラーになる」はman bashの中では

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.
「sh」という名前で bash を動かしたときは、できるだけ昔の sh っぽく動きますよ。

と書かれている。

まとめ

.shファイルを実行する場合
・/bin/shがシンボリックリンクじゃない場合 →.shファイルがshで実行される
・/bin/shがシンボリックリンクの場合 →.shファイルがbashでされる

.bashファイルを実行する場合
・/bin/shがシンボリックリンクじゃない場合 → 実行されない
・/bin/shがシンボリックリンクの場合 →Bashism のみ実行されずかつ、どの部分が Bashism で実行されていないか教えてくれない
・/bin/bashで実行 →.bashファイルがbashで実行される

もう少し踏み込むとPOSIXがonかoffかの違いがあることもわかる。/bin/shはPOSIXがon、/bin/bashはPOSIXがoffになっている。

この記事が気に入ったらサポートをしてみませんか?