猿问

从 golang 程序中执行另一个 go 程序

我想从另一个 go 程序中执行另一个 go 程序并给它 args,如下所示:


package main

func main() {

  //here I want to call a specific go file, e.g. test.go with args

}

测试.go


package main

func main(x int) {

  //do stuff with x

}

我不想发送一个int作为arg,而是像http.ResponseWriter这样的东西

我想到了一个解决方案,但它并不是很好:

  1. 使用 gob 将 http.ResponseWriter 转换为字符串

  2. 从 test.go 读入一行

  3. 将字符串发送到 test.go

感谢您的任何答案:D


ibeautiful
浏览 395回答 3
3回答

侃侃尔雅

有很多方法可以实现互操作性:1- 如果您有双方的源文件,我建议使用标准的 golang 包 (Lib) 调用,而不是互操作性。2-使用“os/exec”:如果您没有源代码,并且只有二进制文件,或者您可以通过文件或文本参数传递参数:你可以像这样传递参数:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "os")func main() {&nbsp; &nbsp; fmt.Println(os.Args[0]) // fileNameAndPath}或使用“标志”标准库:// flags.exe -hpackage mainimport (&nbsp; &nbsp; "flag"&nbsp; &nbsp; "fmt")func main() {&nbsp; &nbsp; namePtr := flag.String("name", "AR", "name")&nbsp; &nbsp; agePtr := flag.Int("age", 3700, "age")&nbsp; &nbsp; flag.Parse()&nbsp; &nbsp; fmt.Println(*namePtr, *agePtr) //AR 3700}/*Usage of flags.exe:&nbsp; -age int&nbsp; &nbsp; &nbsp; &nbsp; age (default 3700)&nbsp; -name string&nbsp; &nbsp; &nbsp; &nbsp; name (default "AR")*/这将提供 -h 的帮助。您可以像这样调用另一个二进制程序或 golang 编译器本身:package mainimport (&nbsp; &nbsp; "log"&nbsp; &nbsp; "os/exec")func main() {&nbsp; &nbsp; cmnd := exec.Command("main.exe", "arg")&nbsp; &nbsp; //cmnd.Run() // and wait&nbsp; &nbsp; cmnd.Start()&nbsp; &nbsp; log.Println("log")}3-另一种方法是使用标准输入/标准输出调用外部程序。这样,您可以通过标准输入/输出发送二进制数据:这里文件“a”调用二进制文件“b”并通过标准输入/标准输出发送和接收:这是我的转换:http : //erlang.org/doc/tutorial /c_port.html(您可以使用 os 命名管道)文件 a:// apackage mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "log"&nbsp; &nbsp; "os/exec"&nbsp; &nbsp; "runtime"&nbsp; &nbsp; "time")var cout chan []byte = make(chan []byte)var cin chan []byte = make(chan []byte)var exit chan bool = make(chan bool)func Foo(x byte) byte { return call_port([]byte{1, x}) }func Bar(y byte) byte { return call_port([]byte{2, y}) }func Exit() byte&nbsp; &nbsp; &nbsp; { return call_port([]byte{0, 0}) }func call_port(s []byte) byte {&nbsp; &nbsp; cout <- s&nbsp; &nbsp; s = <-cin&nbsp; &nbsp; return s[1]}func start() {&nbsp; &nbsp; fmt.Println("start")&nbsp; &nbsp; cmd := exec.Command("../b/b")&nbsp; &nbsp; stdin, err := cmd.StdinPipe()&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; log.Fatal(err)&nbsp; &nbsp; }&nbsp; &nbsp; stdout, err2 := cmd.StdoutPipe()&nbsp; &nbsp; if err2 != nil {&nbsp; &nbsp; &nbsp; &nbsp; log.Fatal(err2)&nbsp; &nbsp; }&nbsp; &nbsp; if err := cmd.Start(); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; log.Fatal(err)&nbsp; &nbsp; }&nbsp; &nbsp; defer stdin.Close()&nbsp; &nbsp; defer stdout.Close()&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case s := <-cout:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stdin.Write(s)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf := make([]byte, 2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; runtime.Gosched()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.Sleep(100 * time.Millisecond)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; stdout.Read(buf)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cin <- buf&nbsp; &nbsp; &nbsp; &nbsp; case b := <-exit:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if b {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Printf("Exit")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return //os.Exit(0)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; go start()&nbsp; &nbsp; runtime.Gosched()&nbsp; &nbsp; fmt.Println("30+1=", Foo(30)) //30+1= 31&nbsp; &nbsp; fmt.Println("2*40=", Bar(40)) //2*40= 80&nbsp; &nbsp; Exit()&nbsp; &nbsp; exit <- true}文件 b:// bpackage mainimport (&nbsp; &nbsp; "log"&nbsp; &nbsp; "os")func foo(x byte) byte { return x + 1 }func bar(y byte) byte { return y * 2 }func ReadByte() byte {&nbsp; &nbsp; b1 := make([]byte, 1)&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; n, _ := os.Stdin.Read(b1)&nbsp; &nbsp; &nbsp; &nbsp; if n == 1 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return b1[0]&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}func WriteByte(b byte) {&nbsp; &nbsp; b1 := []byte{b}&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; n, _ := os.Stdout.Write(b1)&nbsp; &nbsp; &nbsp; &nbsp; if n == 1 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}func main() {&nbsp; &nbsp; var res byte&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; fn := ReadByte()&nbsp; &nbsp; &nbsp; &nbsp; log.Println("fn=", fn)&nbsp; &nbsp; &nbsp; &nbsp; arg := ReadByte()&nbsp; &nbsp; &nbsp; &nbsp; log.Println("arg=", arg)&nbsp; &nbsp; &nbsp; &nbsp; if fn == 1 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = foo(arg)&nbsp; &nbsp; &nbsp; &nbsp; } else if fn == 2 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = bar(arg)&nbsp; &nbsp; &nbsp; &nbsp; } else if fn == 0 {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return //exit&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = fn //echo&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; WriteByte(1)&nbsp; &nbsp; &nbsp; &nbsp; WriteByte(res)&nbsp; &nbsp; }}4 - 另一种方式是使用“net/rpc”,这是从另一个程序调用另一个函数的最佳方式。样本:// rpcpackage mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "net"&nbsp; &nbsp; "net/rpc"&nbsp; &nbsp; "runtime"&nbsp; &nbsp; "sync")var wg sync.WaitGrouptype Server struct{}func (this *Server) Add(u [2]int64, reply *int64) error {&nbsp; &nbsp; *reply = u[0] + u[1]&nbsp; &nbsp; return nil}func server() {&nbsp; &nbsp; fmt.Println("server: Hi")&nbsp; &nbsp; rpc.Register(new(Server))&nbsp; &nbsp; ln, err := net.Listen("tcp", "127.0.0.1:12345")&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(err)&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; c, err := ln.Accept()&nbsp; &nbsp; &nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; continue&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; go rpc.ServeConn(c)&nbsp; &nbsp; }}func client() {&nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; c, err := rpc.Dial("tcp", "127.0.0.1:12345")&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(err)&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Println("Connected...")&nbsp; &nbsp; var result int64&nbsp; &nbsp; err = c.Call("Server.Add", [2]int64{10, 20}, &result)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println(err)&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Server.Add(10,20) =", result)&nbsp; &nbsp; }&nbsp; &nbsp; wg.Done()}func main() {&nbsp; &nbsp; go server()&nbsp; &nbsp; runtime.Gosched()&nbsp; &nbsp; go client()&nbsp; &nbsp; runtime.Gosched()&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; fmt.Println("Bye")}/*output:server: HiConnected...Server.Add(10,20) = 30Bye*/

Smart猫小萌

使用os/exec,您可以像这样调用 go 编译器:output, err := exec.Command("go", "run", "/file/path/to/open").Output()&nbsp;if err == nil {&nbsp; &nbsp; w.Write(output) // write the output with ResponseWriter}Go 不会将参数传递给程序main,例如func main(x int). 在 Go 中执行此操作的方法是使用os.Args.在我看来,您正在尝试在 Go 中使用 PHP 概念,结果不会很好。相反,您应该使用模板和静态文件来实现动态网站。检查包裹text/template。

慕姐8265434

为要从另一个文件运行的包创建一个可执行文件。提供要在其中运行的文件的相对路径exec.Command。例如:文件 Apackage aimport "fmt"func main(){&nbsp; &nbsp; for i:=0;i<10;i++{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;fmt.Println(fmt.Sprintf("Process: %d", i))&nbsp; &nbsp; }}为上述文件创建一个二进制/可执行文件。该文件将位于包内,因此请前往包并运行可执行文件。go build github.com/user/a/a.go // or whatever be your GOPATH for executables to create a binary file下面是linux系统中二进制文件的情况。文件 Bpackage bimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "os/exec")&nbsp; &nbsp;&nbsp;func main(){&nbsp; &nbsp; // come out of package b and then go inside package a to run the executable file as&nbsp; &nbsp; cmd := exec.Command("../a/a.go")&nbsp; &nbsp; if err := cmd.Run(); err != nil{&nbsp; &nbsp; &nbsp; &nbsp;fmt.Println(err)&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答