フロントエンドの環境構築周りで絡んでくるdirenv、shell、bashあたりの理解が怪しかったのできちんと理解すべく整理してみました。あくまでもフロントエンドエンジニアとして知っておくべき最低限の情報だけなので超基本編です。
Shellとは:
LinuxなどのOSにおける核である「カーネル」に要求を出すプログラムのこと。これだけではぴんとこないのですが、とても詳しい説明がありました。これが一番わかりやすかったです。
京都産業大学 情報理工学部のページから引用
UNIX / Linux でターミナルソフト (kterm など)を利用する場合、ユーザはプロンプトで操作目的のコマンドを入力し、そこで表示される結果を見てまた次のコマンド入力を行う、というサイクルで対話的な作業を行います。本当は UNIX / Linux の中核(kernel: カーネル)が管理している機能を用いて、ユーザは様々な処理を行っているのですが、カーネル自身はユーザと直接対話する能力を持っていません。そこで、ユーザと対話する能力を持ち、カーネルに対して操作のお伺いを立てる仲介役のプログラムが、ユーザとカーネルの間に存在してユーザは操作を行います。この仲介役プログラムは、ユーザから見てカーネルの周りをすっぽり覆っている「殻」(shell) のように見えることからシェルと呼ばれます(図1参照)。簡単に言えば、シェルは、ユーザが入力したコマンドを解釈してカーネルに処理を依頼し、その結果やメッセージなどを画面に表示する機能を持っているのです。
実際には、ユーザがログインしてターミナルソフトを起動している間、そのターミナル内でシェルは動き続け、常に対話的な処理の仲介役を担っています。シェルの動作を図示すると図2のようになります。
ユーザーによる命令は直接カーネルに渡されるのではなく、まずシェルが受け取る。シェルは受け取った要求を翻訳してカーネルに渡します。そしてカーネルは、シェルから受け取った翻訳済みの命令を実行するという流れです。要するにシェルは受付窓口のようなものですね。
Shellスクリプトとは:
シェルとシェルスクリプトは別のもので、組み立てられたコマンドひとかたまりの事をシェルスクリプトと呼びます。1種のプログラミング言語のような扱いを受けていますが、機能が貧弱なため、本格的なプログラミングには向いていませんが、繰り返し(for/while/until)や条件分岐(if/case)などの制御文、変数や配列、関数などの仕組みは一通り備えていて、様々な事に応用が効きます。定期作業の自動化、作業の記録、バッチ処理など自動化処理を操るシェルスクリプトをプログラミングして使う事が多いみたいです。
Shellの種類:sh, csh, bash, zsh, tcsh, fish, elvish
sh, csh, bash, zsh, tcsh, fish, elvish
自分の使ってるPCのShellはターミナルでecho $SHELL と打つと確認できます。
結果は個人用のmacは、zshで、
/bin/zsh
会社のmacは、bashでした。
/bin/bash
ちなみに、macOSの標準shellはbashでしたが、「MacOS X Catalina」よりzshらしいです。
bash:Bourne Again Shellの略。バッシュ
zsh:正式名称はZ Shell。ズィーシェル
両者の違いはこちらを参照ください。
色々と使い道があるShellですが、この記事では、direnvを使い、そのディレクトリ固有の環境変数ファイルを作って読み込ませる設定をしてみようと思います。
今更ながら、環境変数とは
macOSやLinuxなどUNIX系のOSでは、環境変数は基本的には.bashrcや.zshrcなどに設定し、シェルを起動すると常に同じ値が適用されます。通常はこれで問題ありませんが、開発するアプリ毎に固有の環境変数を設定したい場合(例:あるアプリのプロジェクトフォルダ内でだけ、環境変数としてAWSの認証キーを設定して使用したい)だと不便です。その環境変数を毎回設定するのも大変ですし、忘れてしまいます。また.bashrcなどに全部設定しロードしておく事もできますが、プロジェクトが増えてくると煩雑になり困ります。
そこで便利なツールがdirenvなのです。
direnvとは
Shellのエクステンションツールで、ディレクトリ毎に環境変数を定義して、そのディレクトリがカレントになった時だけ、その環境変数を有効/無効にしてくれるツール。
direnvはディレクトリ毎に環境変数を定義できて、.envrcというファイルに環境変数を適用します。.envrcがあるディレクトリがカレントディレクトリになった時に環境変数が有効になります。
(.envrcを探すので、存在しなければ関係ない)direnvはdirectory environmentの略だと思います。そのディレクトリ固有の環境変数という事ですね。
また、.envrcと.envは環境変数をソースから分離して定義することでアクセストークンなどを安全に利用できるようにするためのファイルでもあります。
direnvでは .envrc
docker-compose、dotenvでは .env
など、ツールやサービスによってサポートされているファイル名が異なります。
実際にやってみましょう
まずは、direnvをインストールする
mac上でHomebrewを利用しているのであれば、brew install direnv
環境変数を設定したいプロジェクトのルートディレクトリに、.envrcファイルを作ります。
touch .envrc
使いたい環境変数を下記のように設定します。
export 環境変数名 = 値
bashにシェルのフックを設定する(zshでもOK)
自動で読み込むための設定です。
ルートディレクトリに移動して、vimで.bashrc/zshrcを開く
vim ~/.bashrc
もしくは
vim ~/.zshrc
キーボードのiを押すとinsert(入力)モードになるので、以下を記述
なぜこう書くのかまではわかりません、おまじないと思いましょう。
eval "$(direnv hook bash)"
もしくは
eval "$(direnv hook zsh)"
キーボードで:wqと入力すると保存終了。
(たまに:を入力し忘れて入力モードを抜けれなくて焦ります。。)
.bashrcを再読み込みする
source [ファイルパス]で、パスの設定を読み込んで現在のシェルを実行するコマンド
シェルの設定ファイル(.bashrc)を更新した後で、変更内容を実行中のシェルに反映させる。
source ~/.bashrc
もしくは
source ~/.zshrc
.envrcを置いたディレクトリに移動すると、こんなエラーが出ると思うので、
direnv allowを実行してdirenvを許可すれば大丈夫です。これで設定完了。
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
cdコマンドで別のディレクトリ(.envrcのないディレクトリ)に移動すると、この様に環境変数がunloadされます。
direnv: unloading
再び移動するとloadされます。なので、上記の設定は最初だけやればOKです。(ずっと勘違いしてて毎回やってました、、)
direnv: loading .envrc
もし.envrcファイルの設定を書き換えた場合は、自動で.envrcを読み込み直してくれますが、稀にdirenv allowを求めるエラーが出るので、そしたらdirenv allowしてあげればOKです。
最後に、環境変数にはアクセストークンやAPIキーなどが第三者に渡ってしまうとまずいデータを設定することが多いと思うので、.gitignoreに.envrcを追加するのが一般的です。
envrc, bashrcのrcとは?
サクッと調べたらおそらくrun commandsの略という説が濃厚です。
以上です。
↧