Bash
curl
パイプ
ファイルデスクリプタ

【curl hoge | bash - 】curlで取ってきたシェルスクをbashで実行しようとして軽くハマった話

どうも。表題どおりハマったので書いて行きます。

やりたかったこと

よくhomebrewとかpipとかのインストールであるような、ブートストラップシェルスク、あれをやりたかった。

$ curl hoge | bash

こんな感じを想定してた。

うごかなかったところ

シェルスクの中でreadを使ったら入力プロンプトが表示されずにそこでプログラムがなんかエラー吐いて。

原因

理由はよく考えてみれば簡単で、もともとreadは「標準入力(キーボード)やパイプから、改行文字が車で文字列をとってくる」コマンド、つまり、bashにパイプで渡していたシェルスクの本体をreadが読み込んじゃったという話。

なので、なんとかパイプを使わずに、でもファイルに保存とかせずにスクリプトを実行したい。

解決策

そういえばbashでファイルデスクリプタの入力作れるじゃん!ってことで、

$ curl hoge | bash

$ bash <(curl hoge)

にした。この記号が何かっていうと、<()の中のコマンドの実行結果(標準出力)を、仮想的な一時ファイル(Unixソケットバッファ)に保存して、そのファイルデスクリプタをそこの場所に置き換えてくれる。

もっと簡単にいうと、curl hogeの結果が/dev/fd/4とかのバッファに保存されて、<()って書いたところが/dev/fd/4に置き換わる。ファイルを保存しているのと対して変わっていないが、こちらの方がスマートにかけるしわざわざファイルも生成しないので楽。ということ。

まとめ

bashのマイナーな記号知っとくとやっぱり便利だなって(小並感)