導入
3本のスクリプトで、同じ log() 関数をコピペしている。よくある光景ですが、書式を変えたくなった瞬間に3か所直すことになります。共通部分は1つのファイルにまとめて、読み込んで使いましょう。
説明
source ファイル名(短縮形は . ファイル名)は、そのファイルを今のシェルの中で実行します。定義された関数や変数が、そのまま使えるようになります。
#!/bin/bash
# 共通部品を作る(ふだんは別ファイルとして用意しておく)
cat <<'EOF' > common.sh
APP_NAME=becomecoder
log() {
echo "[$APP_NAME] $1"
}
EOF
# 読み込む
source common.sh
log "共通の関数が使えます"
echo "アプリ名: $APP_NAME"
sh common.sh との違いが重要です。
| 書き方 | 実行される場所 | 関数・変数は残る? |
|---|---|---|
sh common.sh | 別のシェル(子プロセス) | 残らない |
source common.sh | 今のシェルの中 | 残る |
flowchart LR
A["script.sh"] -->|"source common.sh"| B["common.sh の中身を<br/>その場で実行"]
B --> C["log() と APP_NAME が<br/>script.sh から使える"]
だから設定ファイルの読み込みにも使われます。config.sh に DB_HOST=… と書いておき、スクリプトの先頭で source config.sh。環境ごとに設定ファイルだけ差し替えれば、スクリプト本体は共通のまま——これが実務の定番構成です。
sourceは「そのファイルの中身を、その場に貼り付けて実行する」のと同じです。だから信頼できないファイルを source してはいけません。書いてあるコマンドが、そのままあなたの権限で実行されます。
やってみよう
スクリプトを実行して、common.sh から読み込んだ log() と $APP_NAME が使えることを確かめましょう。次に source common.sh を sh common.sh に変えて実行してください。関数が見つからず失敗します——この違いが source の存在理由です。
演習
common.sh の APP_NAME を myapp に変えて読み込み、[myapp] 設定を読み込みました と表示してください。
ヒント1を見る
ヒアドキュメントの中の APP_NAME=becomecoder を APP_NAME=myapp に直します。
ヒント2を見る
最後に log "設定を読み込みました" を呼びます。