タイトルの通り、任意のコマンドをWebサーバー化するコマンドを作ってみました。
Go言語で作っているのでクロスプラットフォームで使えます。
使い方は簡単。
こんな感じで viewb の後にWebサーバー化したいコマンドを続けると・・・
実行例
$viewb ls -l /
このように結果をブラウザで確認できるようになります。
アクセスするたびにコマンドが実行されるので、最新の結果が常に返ってきます。
コマンドの代わりにスクリプトを指定すればスクリプトも実行できます。
外部ネットワークとの導通確認してみたり
Ping
$viewb ping -c 1 8.8.8.8
プログラムのテストを実行して結果を確認したり
GoTest
$viewb go test
意味もなくサーバーを立ててみたり
ItWorks
$viewb echo It works!
使い方は無限大。
BASIC認証で鍵をかけることも出来ます。※認証が通るまでコマンドは実行されません。
balse
$viewb -user laputa -pass balse echo booomb!
中身
以下がviewbコマンドのソースです。Go言語で作ってます。
やってることが単純なだけあって、中身も単純です。
スタンドアロンのWebサーバーを簡単に組み込んで配布できるのはGo言語の大きな魅力ですね。
viewb.go
package main
import (
"flag"
"fmt"
"net/http"
"os"
"os/exec"
"runtime"
"strconv"
"strings"
)
var (
port int
user string
pass string
com string
)
func main() {
//parse args
flag.IntVar(&port, "p", 8080, "port /default:8080")
flag.StringVar(&user, "user", "", "user (BASIC AUTH)")
flag.StringVar(&pass, "pass", "", "pass (BASIC AUTH)")
flag.Parse()
com = strings.Join(flag.Args(), " ")
//start server
fmt.Println("http://localhost" + ":" + strconv.Itoa(port))
fmt.Println("Stop: Ctrl+C")
http.HandleFunc("/", handler)
err := http.ListenAndServe(":"+strconv.Itoa(port), nil)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
}
//handler: command result
func handler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=UTF-8")
if auth(r) == false {
w.Header().Set("WWW-Authenticate", `Basic realm="MY REALM"`)
w.WriteHeader(401)
w.Write([]byte("401 Unauthorized\n"))
return
}
fmt.Fprint(w, cmd(com))
}
//exec command
func cmd(commandString string) string {
var command string
var op string
if runtime.GOOS == "windows" {
command = "cmd"
op = "/c"
} else {
command = "/bin/sh"
op = "-c"
}
out, err := exec.Command(command, op, commandString).Output()
if err != nil {
return string(err.Error())
}
return string(out)
}
//basic auth
func auth(r *http.Request) bool {
if user == "" || pass == "" {
return true
}
_user, _pass, ok := r.BasicAuth()
if ok == false {
return false
}
return _user == user && _pass == pass
}
まとめ
実行ファイルはここから落とせます。
viewbでviewbを実行すると厄介なことになるのでやめましょう。