shellscriptだけでウェブサーバーを立てる方法です。
$ php -S 0.0.0.0:3000
これだけで今いるディレクトリのファイルを http://localhost:3000
にアクセスするだけで見ることができます!
知らない人もいると思うので書きました! ぜひ役立ててください!
で終わると思ったか
この世界では……shellscriptだけで動くか動かないかなんだよ!
なので、標準で入っているコマンドだけでウェブサーバーを立ててみようと思います。
Netcatというコマンド
Netcat(nc)とは、Unix系のOSには大体標準で入っている、TCPやUDPのパケットを読み書きすることができるツールです。
例えば。tcpの通信を待ち受けることができます。
次のコマンドでcurlからのリクエストを読み取ってみましょう。
$ nc -k -l 3000 | curl -s localhost:3000
GET / HTTP/1.1
Host: localhost:3000
User-Agent: curl/7.49.1
Accept: */*
おみごと! あなたはcurlからのリクエストを見ることに成功しました。
では、次にncからの情報をブラウザから受け取ってみましょう。
ncから受け取る
ncは待ち受けるだけでなく、pipeを通して接続してきたクライアントに情報を返すことも可能です。
次のコマンドを入力してブラウザから localhost:3000
へアクセスしてみてください。
echo "example" | nc -l 3000
ブラウザ上にexample
の文字を見ることができましたね?
つまり、これを整形して、適切なファイルを送り返すシェルスクリプトを書くだけで、ウェブサーバーが動くということです。
ncコマンドを使って作る一番単純なウェブサーバー
ただ表示するだけのコマンドなら、書く内容はとてもは単純です。
ncで取得できるHTTPヘッダーから、要求されたファイル名を読み取ってそのファイルを表示するだけです。
awkを使って、HTTPと書かれた行だけ取り出してみます。
次のコマンドを入力してブラウザから http://localhost:3000/index.html
へアクセスしてみてください。
$ nc -kl 3000 | awk '/HTTP/{print substr($2, 2)}'
index.html
無事、目的のファイルの名前を取り出すことができました。
ではあとはこれをcatで表示するだけで目的のファイルの内容を見ることができますね。
同じディレクトリに index.html
を作成して、適当なHTMLを書き込んで、次のコマンドを実行してみましょう。
$ nc -kl 3000 | awk '/HTTP/{system("cat " substr($2, 2))}'
ブラウザからアクセスしてみるとコマンドラインに次のように出力されるはずです。
<!DOCTYPE html>
<html lang="en">
<body>
これはテストです
</body>
</html>
みれましたね。あとはブラウザへ返却するだけです。次へ行きましょう。
動くけど動かないコマンド
単純にpipeをつなげてみました。
$ nc -kl 3000 | (awk '/HTTP/{system("cat " substr($2, 2))}'| nc -l 3000)
ですが、このままでは動くけど動きません。
実行してもらえばわかると思いますが、何度かリロードすると、見れる時とみれない時が出てきます。
待ち受けているncと送出するncが重複しているからでしょうか。待ち受けてる時は出せないし、出してる時は受け取れないようです。
どうやら、送受信を同時に上手いことやってくれるわけではないようですね。
pipeでつなげば受け取れることはわかっています。ですので、受け取った内容をそのまま出力できるようにしてみましょう。
mkfifoコマンド
そこで、mkfifoというコマンドの登場です。
ざっくりというと、あるコマンドから受け取った内容をそのままpipeとして返すことができるコマンドです。
このコマンドを利用して、ncから与えられた情報を処理して返すようにしてみます。
$ /usr/bin/mkfifo backpipe
$ nc -kl 3000 -w 1 0<backpipe | awk '/HTTP/{system("cat " substr($2, 2))}' 1>backpipe
ブラウザから http://localhost:3000/index.html
へアクセスしてみましょう。
無事、HTMLファイルが表示されたはずです。
そう、シェルスクリプトだけでウェブサーバーは作れるんです。
最後に
ワンライナーで動くウェブサーバー使えばいいと思います。