英文:
How could I pass a dynamic set of arguments to Go's command exec.Command?
问题
我在这里遇到了一个关于将参数传递给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变量。
如果我有一个参数数组,其数量可能是不确定的,我想要传递这些参数,这是否可行?
英文:
I came across a question on here relating to arguments being passed to Go's exec.Command function, and I was wondering if there was a way do pass these arguments dynamically? Here's some sample code from sed question:
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))
}
So as you can see each arg is defined above as arg0, arg1, arg2 and arg3. They are passed into the Command function along with the actual command to run, in this case, the app var.
What if I had an array of arguments that always perhaps had an indeterministic count that I wanted to pass through. Is this possible?
答案1
得分: 97
像这样:
args := []string{"你", "喜欢", "什么", "就", "用什么"}
cmd := exec.Command(app, args...)
在 golang.org 上查看有关语言和教程的内容。
英文:
Like this:
args := []string{"what", "ever", "you", "like"}
cmd := exec.Command(app, args...)
Have a look at the language and tutorial on golang.org.
答案2
得分: 0
你可以尝试使用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("等待命令完成...")
log.Printf("进程ID为 %v", cmd.Process.Pid)
err = cmd.Wait()
log.Printf("命令完成并出错,现在重新启动:%v", err)
}
然后像这样运行:
$ go run main.go node ../web-test/index.js
2019/01/26 13:32:29 等待命令完成...
2019/01/26 13:32:29 进程ID为 3582
英文:
You can try with the flag library, which has worked for me. This is a different example but it uses the concept of accepting dynamic arguments.
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)
}
And running like this
$ 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
答案3
得分: -1
有两种方法:
- 命令行标志
- 使用配置文件。程序将读取该文件并进行一些初始化操作或获取一些参数等。
配置文件示例
// manifest.json
{
"name": "xxx",
"version": "0.0.0",
"server": {
"port": 8080
}
}
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
var (
Config Settings
)
type Settings struct {
Name string `json:"name"`
Version string `json:"version"`
Server Server `json:"server"`
}
type Server struct {
Port int `json:"port"`
}
func LoadConfig(path string, settings *Settings) {
jsonFile, err := os.Open(path)
if err != nil {
fmt.Printf(`无法打开文件 "%s": %v`, path, err)
}
manifestBytes, _ := ioutil.ReadAll(jsonFile)
if err := json.Unmarshal(manifestBytes, &settings); err != nil {
fmt.Printf("无法将JSON解组为结构体(Settings): %v", err)
}
}
func main() {
LoadConfig("manifest.json", &Config)
paras := []string{Config.Version, fmt.Sprintf("%d", Config.Server.Port)}
print(paras)
// cmd := exec.Command(Config.Name, paras...)
// ...
}
英文:
There have two ways,
- command-line-flags
- use the config file. The program will read this file and do some initialize or get some parameters etc.
Example of the config file.
// manifest.json
{
"name": "xxx",
"version": "0.0.0",
"server": {
"port": 8080
}
}
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
var (
Config Settings
)
type Settings struct {
Name string `json:"name"`
Version string `json:"version"`
Server Server `json:"server"`
}
type Server struct {
Port int `json:"port"`
}
func LoadConfig(path string, settings *Settings) {
jsonFile, err := os.Open(path)
if err != nil {
fmt.Printf(`Unable to open the "%s": %v`, path, err)
}
manifestBytes, _ := ioutil.ReadAll(jsonFile)
if err := json.Unmarshal(manifestBytes, &settings); err != nil {
fmt.Printf("Unable to unmarshal json to struct (Settings): %v", err)
}
}
func main() {
LoadConfig("manifest.json", &Config)
paras := []string{Config.Version, fmt.Sprintf("%d", Config.Server.Port)}
print(paras)
// cmd := exec.Command(Config.Name, paras...)
// ...
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论