Web 上で公開されているシェルスクリプトをローカルで直接実行したい

Gist 上で自分で公開しているシェルスクリプトを直接実行したかった。

パターン1: 単に実行したい

curl -sSL {URL} | sh

curl でシェルスクリプトを取得しつつ、パイプ経由で sh に流している。もっとも簡単かつポピュラーなパターンだと思う。

curl のフラグ指定は -sSL としていて、今回のユースケースにおいて最も汎用性の高い指定を選んでいるつもり。

フラグ 機能
-sS 出力を抑える。ただしエラーの時は出力を出す。
-L HTTP リダイレクトに従う。

パターン2: オプションをつけて実行したい

実は、パターン1 の方法ではオプションを渡した実行ができない。 なのでシェルスクリプトがオプションを取らない場合は良いが、シェルスクリプトがオプションを取る場合は使えない。 対処法としては、sh に第1引数に /dev/stdin を指定すれば良い。*1

curl -sSL {URL} | sh /dev/stdin foo bar

補足: Gist 上のシェルスクリプトの実行

Gist 上にアップロードしたシェルスクリプトを実行するには、シェルスクリプトを raw で得る必要がある。 Gist の UI 上で Raw ボタンを押すと、こういった URL に飛ぶ。

https://gist.githubusercontent.com/msh5/ad8c7e0af6134c0ec5c1d918a4544188/raw/077c817418717406779fa8aad992eda83e1bc4b7/mk-apache20-license.sh

// 省略版
https://gist.githubusercontent.com/{ユーザ名}/{ハッシュ A}/raw/{ハッシュ B}/{ファイル名}

注意したいのは、ハッシュ B の方は Commit ハッシュなので、この URL では最新の変更に追従できないこと。 例えば Gist 上で変更を行っても、変更が反映されていない元のファイルにアクセスしてしまう。 これが意図する動作であればそれに越したことはないが、多くの場合は最新のシェルスクリプトにアクセスしたいのではなかろうか。 実はハッシュ B の部分を消してしまえば、最新の変更に追従できるようにできる。

// 最新の変更に追従してくれる URL
https://gist.githubusercontent.com/{ユーザ名}/{ハッシュ A}/raw/{ファイル名}

補足: この方法の危険性

「悪意のある人によって公開されているものは危ないよね」という話と、 「ネットワークが不安定で中途半端なスクリプトが実行されてしまうと意図しない挙動になるよね」という話。 アドホック性の高い分こういう危険性もあるので、安全なところに置いてあるスクリプトにだけ使ってくれたまへ。

rcmdnk.com

*1:sh はオプション指定が何もないときは空気を読んで /dev/stdin から読んでくれるが、 オプション指定があるとそれが機能しないため、シェルスクリプトの実行さえままならなくなるようだ。