🍺

curlでダウンロードしたシェルスクリプトの実行

2023/01/13に公開

インストール用のシェルスクリプトをcurlでダウンロードして、実行することってたまにありますよね。
よくわからないまま、おまじないのように入力してきたので、理解するためにHomebrewのインストールを例にして説明したいと思います。

https://brew.sh/

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

/bin/bash ~.sh

細かいところは一旦置いといて、大まかに捉えると/bin/bash ~.shとなっているので、bashシェルの起動時に引数としてシェルスクリプトファイルを指定することで、シェルスクリプトを実行しているんだな、ということがわかります。

ちなみに

$ which bash 
/bin/bash

このように/bin/bashでpathが通ってる人は、わざわざ/bin/を付けなくてもbashだけで通ります。pathを明確にするためにわざわざ/bin/が付いてるんだと思います。

シェルスクリプトの実行方法は主に3つ

1つ目がシェル起動時の引数にシェルスクリプトファイルを指定する
2つ目がsourceコマンドの引数にシェルスクリプトファイルを指定する
3つ目がシェルスクリプトファイルにShebang(#!/bin/bash 等)を付与してから、chmodで実行権限を設定することでシェルスクリプトファイルに実行権を付与し、シェルスクリプトを直接実行する

Shebangはインタプリタ(スクリプトを実行する処理系)を指定する仕組みです。
https://e-words.jp/w/シバン.html
https://qiita.com/mohira/items/566ca75d704072bcb26f
長くなりそうなので、シェルスクリプトの実行方法3つに関しては別記事として切り出したいと思います。

bashシェルの-cオプション

続いて以下の部分を見ていきます。

/bin/bash -c "文字列"

このようにbashシェルの-cオプションに文字列を渡すことで文字列をコマンドとして実行させることができます。

以下の違いについて説明すると、

$ bash hoge.sh
$ bash -c './hoge.sh'

上はbashシェルが評価しますが、
下はhoge.shというシェルスクリプトファイルのShebangで指定されたインタプリタで評価されます。例えばShebangが#!/bin/zshだった場合はbashではなくzshで評価される、ということです。

同じ-c オプションでも、どのshellかによって挙動が違うようです。詳しくはこちらの記事を読んでください。
https://qiita.com/ukinau/items/410f56b6d777ad1e4e90

コマンド置換$()

続いて以下の部分を見ていきたいと思います。

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

$()これはコマンド置換と呼びます。
$(コマンド)の部分が、コマンドの実行結果で置換されます。コマンドの実行結果を別のコマンドの引数として利用したい時などに使います。
バッククォート(`) でもコマンド置換ができます。

つまりHomebrewのinstallをする以下のコマンドは

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

↓こういうように解釈されているということになります。

/bin/bash -c "curlコマンドの実行結果"

#!/bin/bashから始まっているのがcurlコマンドの実行結果です。
インタプリタにbashが指定されているのがわかるのでこのシェルスクリプトはbashで評価されることがわかります。
curlの実行結果

よく似てる${}$()の違いについては以下に書いてます。
https://zenn.dev/y__adler/articles/fe932683b603a9

最後に

たった一行のコマンドでも学べることたくさんあるな〜と思いました。

Discussion