curlでダウンロードしたシェルスクリプトの実行
インストール用のシェルスクリプトをcurlでダウンロードして、実行することってたまにありますよね。
よくわからないまま、おまじないのように入力してきたので、理解するためにHomebrewのインストールを例にして説明したいと思います。
/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はインタプリタ(スクリプトを実行する処理系)を指定する仕組みです。
長くなりそうなので、シェルスクリプトの実行方法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かによって挙動が違うようです。詳しくはこちらの記事を読んでください。
コマンド置換$()
続いて以下の部分を見ていきたいと思います。
$(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で評価されることがわかります。
よく似てる${}
と$()
の違いについては以下に書いてます。
最後に
たった一行のコマンドでも学べることたくさんあるな〜と思いました。
Discussion