73
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Shell ScriptAdvent Calendar 2016

Day 13

ShellScriptで作るウェブサーバー

Last updated at Posted at 2016-12-12

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というコマンドの登場です。

参考: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ファイルが表示されたはずです。

そう、シェルスクリプトだけでウェブサーバーは作れるんです。

最後に

ワンライナーで動くウェブサーバー使えばいいと思います。

ワンライナーWebサーバを集めてみた

73
65
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
73
65

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?