我在这里遇到了一个与传递给 Go 的
exec.Command
函数的参数有关的问题,我想知道是否有办法动态传递这些参数?这是 sed 问题的一些示例代码:
package main
import "os/exec"
func main() {
app := "echo"
//app := "buah"
arg0 := "-e"
arg1 := "Hello world"
arg2 := "\n\tfrom"
arg3 := "golang"
cmd := exec.Command(app, arg0, arg1, arg2, arg3)
out, err := cmd.Output()
if err != nil {
println(err.Error())
return
}
print(string(out))
}
因此,如您所见,每个参数在上面定义为
arg0
、arg1
、arg2
和 arg3
。它们与要运行的实际命令一起传递到 Command
函数中,在本例中为 app
var。
如果我有一个参数数组,并且我想要传递的参数数组总是可能具有不确定的计数,该怎么办?这可能吗?
像这样:
args := []string{"what", "ever", "you", "like"}
cmd := exec.Command(app, args...)
查看 golang.org 上的语言和教程。
您可以尝试使用flag库,它对我有用。这是一个不同的示例,但它使用接受动态参数的概念。
package main
import (
"flag"
"log"
"os/exec"
"strings"
)
func main() {
flag.Parse()
arg1, arg2 := strings.Join(flag.Args()[:1], " "), strings.Join(flag.Args()[1:], " ")
cmd := exec.Command(arg1, arg2)
err := cmd.Start()
if err != nil {
log.Fatal(err)
}
log.Printf("Waiting for command to finish...")
log.Printf("Process id is %v", cmd.Process.Pid)
err = cmd.Wait()
log.Printf("Command finished with error, now restarting: %v", err)
}
然后这样跑步
$ go run main.go node ../web-test/index.js
2019/01/26 13:32:29 Waiting for command to finish...
2019/01/26 13:32:29 Process id is 3582
最简单的方法就像Volker的回答一样,使用Variadic(
...
)来辅助。
exec.Command("./myProgram.exe", []string{"foo", "bar"}...)
或者,您可以使用
Stdin
,将您想要传入的所有数据写入缓冲区。
cmd := exec.Command("")
var buf bytes.Buffer
cmd.Stdin = &buf
bur.Write()
您可以考虑使用 JSON 字符串作为输入。然后另一个程序可以读取这个stdin数据来获取你想要传递的内容。
bs, err := json.Marshal(config)
buf.Write(bs)
a.go
package main
import (
"bytes"
"encoding/json"
"fmt"
"log"
"os/exec"
)
type Config struct {
User string
Para []any
}
func main() {
// cmd := exec.Command("./myProgram.exe", []string{"foo", "bar"}...) // call from exe
cmd := exec.Command("go", []string{"run", "program/b.go", "foo", "bar"}...)
// cmd := exec.Command("python", []string{"b.py", "foo", "bar"}...) // call from python
var buf bytes.Buffer
cmd.Stdin = &buf
config := Config{
"Carson",
[]any{
"hello world",
123,
},
}
bs, err := json.Marshal(config)
if err != nil {
panic(err)
}
buf.Write(bs)
out, err := cmd.Output() // run and wait for it finished
if err != nil {
log.Fatal(err)
}
fmt.Printf("output:\n%s\n", out)
}
b.go
或 (myProgram.exe)
package main
import (
"encoding/json"
"fmt"
"io"
"log"
"os"
)
type Config struct {
User string
Para []any
}
func main() {
_, _ = fmt.Fprintf(os.Stdout, "MyProgram Args:%v\n", os.Args[1:])
// fmt.Printf("MyProgram Args:%v\n", os.Args[1:]) // same as above, I just want to emphasize the object it writes to.
bs, err := io.ReadAll(os.Stdin)
if err != nil {
log.Fatal(err)
}
var config Config
if err = json.Unmarshal(bs, &config); err != nil {
log.Fatal(err)
}
_, _ = fmt.Fprintf(os.Stdout, "MyProgram Get:\n%+v", config)
}
b.py
import sys
import json
sys.stdout.buffer.write(str.encode(f"MyProgram Args:{sys.argv[1:]}"))
config_raw: bytes = sys.stdin.buffer.read()
config = json.loads(config_raw)
sys.stdout.buffer.write(str.encode("MyProgram Get:" + json.dumps(config)))
a.go 输出
output:
MyProgram Args:[foo bar]
MyProgram Get:
{User:Carson Para:[hello world 123]}