シェルスクリプトの実行方法4つの違いメモ【Linux】

以下の4つの違いについてメモ。

❶./hoge.sh

❷bash ./hoge.sh

❸source ./hoge.sh

❹. ./hoge.sh(※..の間には半角スペースがあります)

 

まず最初に「❹はどういう書き方なんだ?」と疑問に思うかもしれませんが

実はLinuxには.というコマンドがあるのです。

参考【 source 】コマンド/【 . 】コマンド

 

というわけで表にまとめると以下のようになります。

❶の方法❷の方法❸の方法
シバンが必要?必要どちらでも良い
(どちらにせよbashで実行されるので)
どちらでも良い
(どちらにせよ現在シェルで実行されるので)
実行権限が必要?不要
現在動作しているシェルの影響を受ける?受けない受ける

まず、❸と❹の方法はまったく同じですので、❹は表から除外しています。(sourceコマンドと.コマンドはまったく同じコマンド)

❹は記述量が少なくなるというメリットがありますが、.を見落としやすいというデメリットもあるのでできれば❸の記述方法が良いと思われます。

 

次に❶と❷も、「シバンが必要か」や「実行権限が必要か」という点を除けば同じです。

 

なので大きな違いがあるのは、❶(❷)と❸だけです。

まず、❸には

・sourceコマンドでシェルファイルを実行した場合は、現在動作中のシェルから実行される。
・なので現在動作中のシェルのシェル変数やエイリアスが引き継がれる。

という特徴があります。(表の太赤字の部分です)

 

これはどういう事かというと

例えば、ほとんどのディストリビューションでは、lsコマンドにデフォルトで以下のようなエイリアスが設定されていますが

$ type ls
ls は `ls --color=auto' のエイリアスです

 

この--color=autoというオプションが設定されているおかげで、ファイルの種類別に色が変わって表示されます。

例えば以下のようなファイルを用意します。

hoge.sh

#!/bin/bash
ls /

そして以下のようにsourceコマンドでhoge.shを実行すると

ファイルの種類別に色が変わるのを確認できます。

▲ファイルの種類によって色が変わる(使用しているターミナルソフト:Rlogin)

 

では次にbashコマンドでhoge.shを実行してみましょう。

するとどうでしょう、今度は色が変わりません。

 

これは以下のような違いがあるからです。

  • sourceコマンドで実行すると・・・
    →現在実行中のシェル(例えばUbuntuの場合はログインシェルがbash)に処理させる。
  • bashコマンドで実行すると・・・
    →新たに子プロセスでbashを立ち上げて、その子bashに処理させる。
    (子bashは.bashrcファイルを読み込んでいないのでエイリアスなどの設定が反映されていない。なので色が変わらない。)

 

--color=autoのエイリアスは~/.bashrcファイルで設定されていますが

▲~/.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
Linux
スポンサーリンク
この記事を書いた人
penpen

1991生まれ。
2019年くらいからフロントエンドエンジニアを目指している元アフィリエイターです💩

penpenをフォローする
penpenをフォローする
penpenメモ

コメント

タイトルとURLをコピーしました