实现在线运行代码的一种方法
通过http post
方法将代码上传至服务器。
服务端:
package main
import (
"bytes"
"fmt"
"io/ioutil"
"log"
"net/http"
"os/exec"
"syscall"
"time"
)
func main() {
http.HandleFunc("/code-compile", codeCompile)
server := &http.Server{
Addr: ":8080",
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 1 << 20,
}
err := server.ListenAndServe()
if err != nil {
log.Fatal("listen and serve: ", err)
}
}
func codeCompile(w http.ResponseWriter, r *http.Request) {
var stdoutBuf, stderrBuf bytes.Buffer
b, _ := ioutil.ReadAll(r.Body)
fmt.Println(string(b))
w.Header().Set("Content-Type", "text/html")
cmd := exec.Command("bash", "-c", string(b))
cmd.Stdout = &stdoutBuf
cmd.Stderr = &stderrBuf
cmd.Start()
done := make(chan error)
go func() {
done <- cmd.Wait()
}()
// 设置超时,否则代码可能无限跑下去
after := time.After(3 * time.Second)
select {
case <-after:
cmd.Process.Signal(syscall.SIGINT)
cmd.Process.Kill()
w.Write([]byte("执行超时"))
case <-done:
// 将输出和错误都返回给请求
w.Write(stdoutBuf.Bytes())
w.Write(stderrBuf.Bytes())
}
}
配合python
或者go run
指令等,并等待返回结果,超时强制中断。
错误显示:
可以结合docker,防止对本机造成重大影响:
$ docker run --rm ubuntu echo $USER
hqinglau