以下の4つの違いについてメモ。
❶./hoge.sh
❷bash ./hoge.sh
❸source ./hoge.sh
❹. ./hoge.sh(※.と.の間には半角スペースがあります)
まず最初に「❹はどういう書き方なんだ?」と疑問に思うかもしれませんが
実はLinuxには.というコマンドがあるのです。
というわけで表にまとめると以下のようになります。
| ❶の方法 | ❷の方法 | ❸の方法 | |
|---|---|---|---|
| シバンが必要? | 必要 | どちらでも良い (どちらにせよbashで実行されるので) |
どちらでも良い (どちらにせよ現在シェルで実行されるので) |
| 実行権限が必要? | 不要 | ||
| 現在動作しているシェルの影響を受ける? | 受けない | 受ける | |
まず、❸と❹の方法はまったく同じです。
なので❹は表から除外しています。(sourceコマンドと.コマンドはまったく同じコマンド)
❹は記述量が少なくなるというメリットがありますが
.を見落としやすいというデメリットもあります。なのでできれば❸の記述方法が良いと思われます。
次に❶と❷も、「シバンが必要か」や「実行権限が必要か」という点を除けば同じです。
なので大きな違いがあるのは、❶(❷)と❸だけです。
❸には
・sourceコマンドでシェルファイルを実行した場合は、現在動作中のシェルから実行される。
・なので現在動作中のシェルのシェル変数やエイリアスが引き継がれる。
という特徴があります。(表の太赤字の部分です)
これはどういう事かというと
例えば、ほとんどのディストリビューションでは、lsコマンドにデフォルトで以下のようなエイリアスが設定されていますが
$ type ls ls は `ls --color=auto' のエイリアスです
この--color=autoというオプションが設定されているおかげで、ファイルの種類別に色が変わって表示されます。
例えば以下のようなファイルを用意します。
hoge.sh
#!/bin/bash ls /
そして以下のようにsourceコマンドでhoge.shを実行すると
ファイルの種類別に色が変わるのを確認できます。
では次にbashコマンドでhoge.shを実行してみましょう。
するとどうでしょう、今度は色が変わりません。
これは以下のような違いがあるからです。
sourceコマンドで実行すると・・・
→現在実行中のシェル(例えばUbuntuの場合はログインシェルがbash)に処理させる。
bashコマンドで実行すると・・・
→新たに子プロセスでbashを立ち上げて、その子bashに処理させる。
(子bashは.bashrcファイルを読み込んでいないのでエイリアスなどの設定が反映されていない。なので色が変わらない。)
--color=autoのエイリアスは~/.bashrcファイルで設定されていますが
設定ファイルの読み込みは以下のように異なります。
- ログインシェルの場合:
→~/.bashrcや~/.bash_profileや/etc/profileなどが読み込まれている
- 子プロセスのシェルの場合
→何も読み込まれない
これが色が変わらないカラクリです。
まとめ
sourceコマンドだと現在動作中のシェルの
- エイリアス
- シェル変数
などの影響を受ける。つまりログイン環境によって必ずしも毎回同じ動作になるとは限らない。
逆に、sourceコマンドを使うべきタイミングとしては
- 現在実行中のシェルのエイリアスやシェル変数を引き継ぎたい場合
- 現在実行中のシェルにエイリアスやシェル変数を登録したい場合
などがあると思われます。
例えば、以下のように.bashrcは.bash_profileから呼び出される設定になっていることが多いですが、これは現在実行中のシェルにエイリアスなどの設定を反映させるためです。
.bash_profile の一部
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
(Ubuntuの場合はsourceコマンドではなくて.コマンドで書かれていました)
そんな感じです。
おわり
- テストした環境:
- Ubuntu 18.04.4 LTS
- bash 4.4.20



コメント