sequenceDiagram
participant A as シェル
participant B as bash
participant C as hello.sh
A->>C: カーネルがインタプリタの読み取り
A->>B: shebangに従い<br>子シェルを起動
B->>C: スクリプトの読み込み<br>と実行
shebangとは?
Definition 1 shebang
シェルスクリプトの1行目は#!で始まり,その後にプログラムを解釈実行するインタプリタのパスを書く. これをshebangと呼ぶ.
shebangと言語
| インタプリタ | 記法 |
|---|---|
| Bourne shell | #!/bin/sh |
| bash | #!/bin/bash |
| perl | #!/usr/bin/perl |
| python | #!/usr/bin/python |
Noteシェルスクリプト実行と必要権限
- バイナリ形式のファイルは実行権限のみで実行できるが,シェルスクリプトの場合は実行権限 + 読み込み権限が必要
bash <script-path>とすれば読み込み権限のみで実行可能
shebangにおける/bin/bashと/usr/bin/bashの違い
shebangでインタプリタを設定する方法は色々ありますが,
#!/bin/bash#!/usr/bin/bash
というパターンをみることがあります (前者のほうがメジャーですが).
$ which bash
/usr/bin/bashなので,terminal上で実行するシェルと起動を合わせようと思うと後者のほうが良さそうですが,どちらも実行可能な場合,Linuxにおいては2つの間に挙動上の差はありません.
/bin/は/usr/binと実体は同じ
ls -il で /bin/bash と /usr/bin/bash を比較してみると同じi-node番号なので挙動上差がない事がわかります
$ ls -li /usr/bin/bash /bin/bash
32768586 -rwxr-xr-x 1 root root 1446024 Mar 31 2024 /bin/bash*
32768586 -rwxr-xr-x 1 root root 1446024 Mar 31 2024 /usr/bin/bash*Linux環境ならば /bin/bash と /usr/bin/bash どちらもbashをインタプレタとして利用できますが,Macとかだと
% which bash
bin/bashで/usr/bin/bashが存在しないケースがあります.そのため,一般的には #!/bin/bash のほうが好ましいといえます.
インタプリタの種類
NoteTL:DR;
インタプリタの種類は本質的には以下の2種類
- どのインタプリタが実行するか
- 子プロセス(サブシェル)か,現在のシェルか
| 方法 | 子プロセス | shebang | 環境への影響 |
|---|---|---|---|
./hello.sh |
あり | 読む | 影響なし |
bash hello.sh |
あり | 読まない | 影響なし |
source hello.sh |
なし | 読まない | 影響あり |
. hello.sh |
なし | 読まない | 影響あり |
カレントディレクトリにhello.shという以下のファイルを作成したとします.
#!/bin/bash
echo 'Hello World!'
dateこのhello.shの実行方法として以下の4つがあります:
## (1) shebangのインタプリタを利用
$ ./hello.sh
## (2) ユーザー指定でbash インタプリタを使用(shebangは読まない)
$ bash ./hello.sh
## (3) 自身のシェルをインタプリタとして使用(shebangは読まない)
$ source ./hello.sh
## (4) 自身のシェルをインタプリタとして使用(shebangは読まない)
$ . ./hello.sh(1) ./hello.sh
(2) bash ./hello.sh
sequenceDiagram
participant A as シェル
participant B as bash
participant C as hello.sh
A->>B: インタプリタを起動
B->>C: スクリプトの読み込み<br>と実行
(3) source ./hello.sh 及び (4) . ./hello.sh
sequenceDiagram
participant A as シェル
participant C as hello.sh
A->>C: スクリプトの読み込み<br>と実行