1. 概要

.bashrc ファイルは、Bashシェルがインタラクティブに起動したときに実行されることがわかっています。

インタラクティブシェルセッションを初期化します。 通常、 .bashrcファイルは、エイリアスと事前定義された関数を配置するのに最適な場所です。

このクイックチュートリアルでは、.bashrcファイルに追加のファイルを含める方法を見てみましょう。

2. 問題の紹介

場合によっては、保守を容易にするために、いくつかのBash設定または関数を別々のファイルに保存し、それらを.bashrcに含めたい場合があります。

ただし、ファイルを正しくインクルードしないと、これは失敗します。 問題をすばやく理解するための例を見てみましょう。

2.1. 追加のスクリプトファイル

スクリプトファイルadditional_script.shがあるとしましょう。

$ cat /home/kent/bin/additional_script.sh
#!/bin/bash
echo "Loading the additional_script.sh file"
CONF_LOADED=true

alias lecho="echo 'Linux Rocks!'"

#function to print local times of 3 citites
function world_clock {
  echo "New York Time:" $(TZ="America/New_York" date +"%F %H:%M:%S")
  echo "Paris Time   :" $(TZ="Europe/Paris" date +"%F %H:%M:%S")
  echo "HongKong Time:" $(TZ="Asia/Hong_Kong" date +"%F %H:%M:%S")
}
echo "additional_script.sh loaded."

additional_script.sh ファイルでは、変数、エイリアス、および関数を定義しました。

2.2. [X15X] $ HOME /.bashrcファイルにadditional_script.shを含めようとしています

次に、 additional_script.sh ファイルを実行可能にして、 $ HOME /.bashrcファイルに行を追加しましょう。

$ tail -1 ~/.bashrc
/home/kent/bin/additional_script.sh

次に、新しいBashシェルを起動して、Bashにadditional_script.shファイルが含まれているかどうかを確認しましょう。

$ bash
Loading the additional_script.sh file
additional_script.sh loaded.

ログメッセージを見ました。 Bashがファイルを見つけてインクルードしたようです。 すごい!

定義した変数、エイリアス、および関数が期待どおりに機能するかどうかを確認するために、いくつかのテストを実行してみましょう。

$ echo $CONF_LOADED

$ lecho
bash: lecho: command not found
$ world_clock
bash: world_clock: command not found

上記の出力が示すように、それらのどれも機能していません。

次に、なぜこれが起こっているのか、そして問題を解決する方法を理解しましょう。

3. $ HOME /.bashrcファイルにadditional_script.shを適切に含める

スクリプトファイルのパスを.bashrcファイルに追加することにより、additional_script.shファイルを.bashrcに含めようとしました。 しかし、期待どおりに機能しませんでした。

別のスクリプトファイルを呼び出したりインクルードしたりする場合、これはかなり一般的な落とし穴です。 それでは次に、なぜそれが起こるのかを理解しましょう。

3.1. スクリプトの実行とスクリプトの調達の違い

Bashはファイル名/home/kent/bin/additional_script.shを確認すると、スクリプトを実行します。

さらに遠く、 Bashがスクリプトを実行すると、新しいシェルプロセスでスクリプトが実行されます。 この新しいシェルプロセスは、現在のシェルの子プロセスです。 したがって、この新しいシェルを「サブシェル」と呼ぶこともできます。

実行されたスクリプトが出力を生成する場合、出力は現在のシェルにコピーされます。 そのため、ログメッセージが表示されています。

ただし、スクリプトによって、変数の変更や新しいエイリアスや関数の宣言など、環境に変更が加えられた場合、変更はサブシェルでのみ有効になります。

Bashがスクリプトを実行した後、サブシェルプロセスは終了します。 したがって、当然、サブシェルへの変更も失われます。 これは、変数、新しいエイリアス、および関数が現在のシェルで機能しなかった理由を説明しています。

私たちが達成したいのは、これらの変更を現在のシェルの環境に適用することです。 したがって、sourceコマンドはまさに私たちが探しているものです。

簡単に言えば、スクリプトの実行とは異なり、スクリプトを調達すると、現在のシェルのスクリプト内のコマンドが実行されます。 したがって、環境へのすべての変更は、現在のシェルで有効になります。

3.2. sourceコマンドの使用

次の2つの形式のいずれかを使用して、スクリプトを入手できます。

source SCRIPT_FILE
. SCRIPT_FILE

どちらの形式もまったく同じように機能します。 このチュートリアルでは、最初のチュートリアルを使用します。

それでは、 source コマンドを使用して、 $ HOME /.bashrcファイルの問題を修正しましょう。

$ tail -1 ~/.bashrc
source /home/kent/bin/additional_script.sh

次に、新しいBashシェルを起動して、スクリプトファイルが正しく含まれているかどうかを確認しましょう。

$ bash
Loading the additional_script.sh file
additional_script.sh loaded.

$ echo $CONF_LOADED
true

$ lecho
Linux Rocks!

$ world_clock
New York Time: 2021-09-26 19:07:22
Paris Time   : 2021-09-27 01:07:22
HongKong Time: 2021-09-26 07:07:22

今回は、ご覧のとおり、ログメッセージが出力されただけでなく、 CONF_LOADED 変数、 lecho エイリアス、およびworld_clock関数が読み込まれました。現在のシェルに。

だから、私たちは問題を解決しました。

4. エラー処理と複数のファイルの包含

これまで、 source コマンドを使用して、.bashrcに追加のスクリプトを含める方法を学びました。

ソースを作成する前にファイルが存在するかどうかを確認することをお勧めします。したがって、sourceコマンドを次のように改善できます。

if [ -f /home/kent/bin/additional_script.sh ]; 
then
    source /home/kent/bin/additional_script.sh
else
    echo "File Not Found: /home/kent/bin/additional_script.sh"
    # ... other error handlings
fi

また、.bashrcに複数のファイルを含めることもできます。  「if」ブロックを何度も複製する代わりに、ループと配列を使用してそれらをチェックして含めることができます。

files_to_source=("/path/to/script1" "/path/to/script2")

for file_to_source in ${files_to_source[@]}
do 
    if [ -f "$file_to_source" ];
    then
        source "$file_to_source"
        echo "Loaded $file_to_source"
    else
        echo "File Not Found: $file_to_source"
        # ... additional error handlings
    fi
done

5. 結論

このチュートリアルでは、スクリプトの実行とBashでのスクリプトのソーシングの違いについて説明しました。

また、例を通じて.bashrcファイルに追加のスクリプトを含める方法についても説明しました。