我有一个写/更新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构建的情况下实现
很难准确理解你想要的东西。但我怀疑这只是想要从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)
}
你所有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