LoginSignup
63
65

More than 5 years have passed since last update.

任意のコマンドをWebサーバー化する

Last updated at Posted at 2015-08-08

タイトルの通り、任意のコマンドをWebサーバー化するコマンドを作ってみました。
Go言語で作っているのでクロスプラットフォームで使えます。

viewb -Github

使い方は簡単。

こんな感じで viewb の後にWebサーバー化したいコマンドを続けると・・・

実行例
$viewb ls -l /

このように結果をブラウザで確認できるようになります。
アクセスするたびにコマンドが実行されるので、最新の結果が常に返ってきます。
コマンドの代わりにスクリプトを指定すればスクリプトも実行できます。

viewb_ss.png

外部ネットワークとの導通確認してみたり

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を実行すると厄介なことになるのでやめましょう。

63
65
2

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
63
65