Golang可执行刷新

问题描述 投票:-5回答:2

我有一个写/更新json的函数。但我需要停止可执行文件,再次运行go build并重新运行可执行文件以在url中更新json。

例如,我有一个Handler.go文件,它将URL中的参数作为键并运行if条件并更新json。所以如果构建可执行文件之前的json值是{“Name”:“Sneha”}并且我在url中传递参数“Nair”,则json在服务器中更新为{“Name”:“Nair”},但是没有得到在URL中更新。所以我必须停止可执行文件,再次运行go build并再次运行可执行文件以反映URL中的新json值{“Name”:“Nair”}。

有人可以提出另一个想法吗?

2.我们可以在函数内运行go build或update吗?

非常感谢。

PS:我有goagain.go的URL。但我不确定这是否符合我的要求。

Handler.go

func handler(w http.ResponseWriter, r *http.Request) {
    keys, ok := r.URL.Query()["key"]
    if !ok || len(keys) < 1 {
        log.Println("Url Param 'key' is missing")
        return
    }
    key := keys[0]
    log.Println("Url Param 'key' is: " + string(key))
    if key == "java" {

         commands := []string{
        "Version=`java -version`",
        "sed -i -e 's/^\\( *Name: *\\) .*$/        Name:\"Java\",/' Handler.go",
        "sed -i -e 's/^\\( *Version: *\\) .*$/        Version:\" '$Version'\",/' Handler.go",   

    }
        exe_cmd(commands)

    }

    if key == "go" {

         commands := []string{
        "Version=`go version`",
        "sed -i -e 's/^\\( *Name: *\\) .*$/        Name:\"Go\",/' Handler.go",
        "sed -i -e 's/^\\( *Version: *\\) .*$/        Version:\" '$Version'\",/' Handler.go",   

    }
        exe_cmd(commands)

    }

    GetHands := GetHand{

            Name:"java",
            Version:" 1.7.0_71",

            }

if err := json.NewEncoder(w).Encode(GetHands); err != nil {
        panic(err)
    }

所以在运行这个包时,url显示json值:{“name”:“java”,“version”:“1.7.0_71”}如果我调用url:http://localhost:8080/?key=go这个Handler.go更新到,

GetHands := GetHand{

        Name:"go",
        Version:" 1.9",

        }

如果我停止可执行文件,再次运行go build并再次运行可执行文件,url将返回为:{“name”:“go”,“version”:“1.9”}

所以基本上我需要动态url,在命中http:/ localhost /?key = go时会返回go的相应值和htpp:// localhost /?key = java会返回java的相应值。这应该在不重新启动可执行文件或重新运行go构建的情况下实现

go
2个回答
1
投票

很难准确理解你想要的东西。但我怀疑这只是想要从shell命令中提取输出并将其写入JSON的本质。

为此,无需修改Handler.go文件或执行go build。您可以直接将输出写入GetHand结构。

一个基本的例子如下:

    package main

    import (
        "fmt"
        "os/exec"
    )

    var cmds = map[string][]string{
        "go":   []string{"/usr/local/go/bin/go", "version"},
        "java": []string{"java", "-version"},
    }

    type GetHand struct {
        Name    string
        Version string
    }

    func handleKey(key string) (*GetHand, error) {

        cmd := cmds[key]
        if cmd == nil {
            return nil, fmt.Errorf("No such key : %v", key)
        }

        b, err := exec.Command("/usr/local/go/bin/go", "version").Output()
        if err != nil {
            return nil, err
        }
        return &GetHand{
            Name:    key,
            Version: string(b),
        }, nil
    }

    func main() {
        h, err := handleKey("go")
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println(h)

        h, err = handleKey("java")
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Println(h)
    }

0
投票

你所有sed的当前代码试图修改你的源代码。它不起作用。一些古老的做法(通常使用bash)实际上做了那种工作人员,但它已经过时且有问题。

至于go,你肯定知道go是一种编译语言,它将源代码编译成二进制文件。这样,对源代码的任何修改都不会影响二进制文件,并导致进程运行时不知道这一点。从这个意义上讲,通过流程修改源代码本身就是错误和无效的。即使可以使用编译器来重建二进制文件,它也会既危险又低效。不要这样做。

在您指定的情况下,有一个更好,更常见的做法:变量。你肯定每天都用它。将GetHands的字段设置为所需值是最简单的。通过这样做,您对每个请求的响应(您称之为URL,但它是错误的)将会改变,因为GetHands的字段会变为变量。

我写下面的代码:

import (
    "os/exec"
    "regex"
    "runtime"
)

var pattern = regexp.MustCompile(`version \"(.+)\"`)

func GetJavaVersion() string {
    cmd := exec.Command("Java", "-version")
    out, err := cmd.Output()
    if err != nil {
        panic(err)
    }
    return string(pattern.FindSubmatch(out)[1])
}

func GetGoVersion() string {
    return runtime.Version()[2:]
}

func handler(w http.ResponseWriter, r *http.Request) {
    keys, ok := r.URL.Query()["key"]
    if !ok || len(keys) < 1 {
        log.Println("Url Param 'key' is missing")
        return
    }
    key := keys[0]
    log.Println("Url Param 'key' is: " + string(key))

    var GetHands GetHand

    if key == "java" {
        GetHands = GetHand{Name: "java", Version: GetJavaVersion()}
    }

    if key == "go" {
        GetHands = GetHand{Name: "go", Version: GetGoVersion()}
    }

    if err := json.NewEncoder(w).Encode(GetHands); err != nil {
        panic(err)
    }
}

因此,对于go,你可以从包runtime中获取版本信息,尽管信息以“go”开头。你可以简单地切片。对于java,你必须运行一个命令:与你的orignal代码相同:java -version。但是不是将它传递给sed,而是通过使用Command.Output从中获取输出,然后使用regexp查找版本信息。 regexp是从字符串中获取信息的非常有用的工具。你可以读一下here

© www.soinside.com 2019 - 2024. All rights reserved.