英文:
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...)
// ...
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论