Question

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?

Was it helpful?

Solution

Like this:

args := []string{"what", "ever", "you", "like"}
cmd := exec.Command(app, args...)

Have a look at the language and tutorial on golang.org.

OTHER TIPS

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

There have two ways,

  1. command-line-flags
  2. 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...)
    // ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top