はじめに
こんにちは、「ゼロからわかる Linuxコマンド200本ノック」という教材を用いてLinuxの勉強をしています
こちらの教材、なぜ?ということを先読みして書いてくれている書籍でLinux自体が難しくてわからないということはありましたが、仕組みがわかればそれについての詳細を説明してくれている書籍です
書籍の紹介はこれくらいにして、本日は本書で触れられていたsourceコマンドについて理解を深めていこうと思います
環境:
ホストOS:Winows 11
仮想化ソフトウェア:Oracle Virtualbox
ゲストOS:ubuntu 24.04.1
sourceの概要
sourceコマンドは、スクリプトや設定ファイルを現在のシェルで実行するためのコマンドです。
sourceを使うと、新しいシェル(サブシェルではないよ)を生成せずに、現在のシェル環境でコマンドが実行されます。
そのため、変数の定義や設定変更が即座に現在のシェルに反映される特徴があります。
本書ではシェルスクリプトを実行する手段の1つとして挙げられていました。
ですが、sourceをシェルスクリプトで実行するのは実際にはあまり使用されておらず、~/.bashrcの変更を反映させるために使用するようです。
※sourceは親シェル上で操作を行うため、環境変数のことを考慮するとexec $SHELL -lを実行して再起動するのを現場では使用されるようです。
では、なぜシェルスクリプトを実行する際にsourceを使用しないのか、sourceを~/.bashrcの変更を反映させるためになぜ使用するのかについて説明していきます
シェルスクリプトを実行する際にsourceを使用しない理由
シェルスクリプトを実行する際、通常は子プロセスのシェル(サブシェルではない)が生成されて、その中でスクリプトが実行されます。
本書でも紹介いましたが、上記の子プロセスのシェル(サブシェルではない)が生成されるパターンを1つ紹介します
- ファイル名を指定して実行
ファイル名が~/bin/lslink.shだとするとこのまま実行するケースです。通常は実行権がないのでchmodで実行権を付与します
$ ~/bin/lslink.sh
bash: /home/ユーザ名/bin/lslink.sh :許可がありません
$ chmod a+x ~/bin/lslink.sh
# すべてのユーザに実行権を与える
話を戻しますが、このような新しい子プロセスのシェル(サブシェルではない)を生成する方法では、親シェルには直接影響を与えないため、親シェル内の環境変数や設定を守りつつスクリプトを安全に実行できます。
sourceを使用すると、スクリプトが現在のシェルで実行されるため、変数や設定が親シェルに反映されてしまい、他のコマンドやプロセスに影響を与える可能性があるため、通常は避けられます。
sourceを~/.bashrcの変更を反映させるために使用する理由
~/.bashrcは、シェルの環境設定ファイルで、エイリアスやシェル変数の定義が含まれています。~/.bashrcは起動時に読み込まれるファイルと思っておいてください。
通常、シェルが起動したときに自動的にこのファイルが読み込まれますが、ファイルを編集した後は再度シェルを開かない限り、変更は親シェルに反映されません。
ここでsourceが役立ちます。
sourceは通常とは違い、スクリプトが現在のシェルで実行されます。
source ~/.bashrcを実行することで、シェルの再起動(ログアウト・ログインや新しいターミナルの起動)をせずに、編集内容を即座に親シェルに反映させることができます。
再起動せずに、即時に新しい設定を反映できる点がsourceを使う最大の理由です。
※sourceは親シェル上で操作を行うため、環境変数のことを考慮するとexec $SHELL -lを実行して再起動するのを現場では使用されるようです。
シェルを再起動する場合、例えばターミナルを閉じて再度開く必要がありますが、作業中にこれを行うのは不便です。また、子プロセスのシェル(サブシェルではない)では親シェルの変更が反映されないため、sourceを使うことで、既存のセッションを維持しながらも新しい設定を利用することができるのでとても便利です
サブシェルについて(追記)
かっこ書きで(サブシェルではない)と記載をさせていただいたのですが、サブシェルとbashや~/bin/lslink.shを実行した際に生成されるシェルは子プロセスのシェルであるということです。
この記事を載せた際には、上記の2つは同じものであるととらえていたのでサブシェルと書きましたが、コメントで別物であると教えていただいたので修正しました。
子プロセスはシェルの環境には直接影響しないという点ではサブシェルと似ていますが、OSのプロセス管理に依存するため、Bashの内部で管理されるサブシェルよりも独立性が強いという特徴があるようです。
また、サブシェルのほうがBash の中で軽量なプロセスとして生成されるため、生成によって他プロセスへのパフォーマンス影響が少ないようですが、子プロセスのシェルはOSレベルでのプロセス管理が行われいるため、数が膨大になるとパフォーマンスに影響を及ぼす可能性があるようです。
これらの詳しい内容について、もう少し深堀するためにはシステムコールについて理解する必要がありまだ未学習のため私の説明では限界があるので
詳しく知りたいという方は以下にリンクを載せておきます。ぜひ読んでみてください
まとめ
少し長くなりましたが、簡単にまとめてみました。
- sourceコマンドの役割
sourceはスクリプトや設定ファイルを新しいシェルを作らずに、現在のシェルで実行し、即座に反映させるために使います。 - シェルスクリプト実行時にsourceを使用しない理由
通常のシェルスクリプトは新しい子プロセスのシェル(サブシェルではない)で実行され、親シェルに影響を与えないため、sourceは必要ありません。 - sourceを使用して~/.bashrcの変更を反映する理由
source ~/.bashrcを使うと、シェルの再起動をせずに設定変更が即座に反映されるため効率的ですが、環境変数のことを考慮するとexec $SHELL -lを実行して再起動するのを現場では使用されるようです。