🐚

Homebrew install時の最後の一手間で何をしているか

2024/04/12に公開

新しくMac miniをサーバー用途で再セットアップする機会があった。
Macのセットアップ時の作業にHomebrewの導入がある。一般的なエンジニアであれば全員が入れていると思う。
Shellを雰囲気で使っているので少し読んでみようと思った次第。

見ていく

2024/04/12現在では公式サイトの導入コマンドは以下のようになっている。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

これを行うとAppleSilicon環境であれば

Warning: /opt/homebrew/bin is not in your PATH.
  Instructions on how to configure your shell for Homebrew
  can be found in the 'Next steps' section below.
==> Installation successful!

///省略

==> Next steps:
- Run these two commands in your terminal to add Homebrew to your PATH:
    (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/alice/.zprofile
    eval "$(/opt/homebrew/bin/brew shellenv)"

と説明されるのでまあPATHに/opt/homebrew/binがないからこのコマンドでいい感じに入るのだろうとぼんやり思いながら以下のコマンドを叩いている。

(echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/alice/.zprofile
    eval "$(/opt/homebrew/bin/brew shellenv)"

大凡理解は合っているはずだがこのコマンドでは実際何をしているのかが気になったので、調べてメモを残す。

two commandsとあるので

  • (echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/alice/.zprofile
  • eval "$(/opt/homebrew/bin/brew shellenv)"

この二つであることは流石にわかる。(逆にこの程度から書くレベル感の記事だ)
eval "$(/opt/homebrew/bin/brew shellenv)"が両方に出てきていることもわかる。

$()では()内に書いたコマンドを実行してくれる。
evalはeval [文字列]の場合に文字列で指定したコマンドを実行する、という機能になるらしい。
そのまま実行すれば良いのでは?と思わなくもないが・・・ああ、いやそうではないか。
$([shellenvの出力])をコマンドとして認識してくれるわけか。
それではshellenv.shの中身を見に行ってみる。

https://github.com/Homebrew/brew/blob/master/Library/Homebrew/cmd/shellenv.sh

コメントを見るに出力されるコマンドはPATHにhomebrewのパスを登録するもののようなので

と説明されるのでまあPATHに/opt/homebrew/binがないからこのコマンドでいい感じに入るのだろうとぼんやり思いながら以下のコマンドを叩いている。

の認識はどうやら合っていそうな雰囲気。
なのでeval "$(/opt/homebrew/bin/brew shellenv)"はHomebrewのパスを通すコマンドだ。

なので、
(echo; echo 'eval "$(/opt/homebrew/bin/brew shellenv)"') >> /Users/alice/.zprofile

(echo; echo '[Homebrewのパスを通すコマンド]') >> /Users/alice/.zprofile
になる。

echoは引数をそのまま返してくれるコマンド、という理解でいたが、リダイレクションというファイルへ書き込む仕組みと組み合わせると
echo "hogehoge" >> ファイル名
でファイルにhogehogeという文字列を書き込める。>>であれば追記。>は上書きなので注意。
その上で考えると
(echo; echo '[Homebrewのパスを通すコマンド]') >> .zprofile

.zprofileというファイルにHomebrewのパスを通すコマンドを書き込む

という意味合いになる。
.zprofileはシェル起動時に毎回呼ばれるファイルだったはず・・・なのでいい感じにパスを最新化させるようにしているということなのだろう。

まとめ

予想を超えない処理ではあったが段階を踏んで分けていけば読み解けることがわかった。シェルは便利と聞くので習熟したいところ。

参考

Discussion