func RunCommandline(cmdline string) error {
	args, err := shlex.Split(cmdline)
	if err != nil {
		return err
	}
	if len(args) < 1 {
		return errors.New("shellx: no command to execute")
	}
	return Run(args[0], args[1:]...)
}
RunCommandline is like Run but its only argument is a command
line that will be splitted using the google/shlex package
package shellx
import (
	"errors"
	"os"
	"os/exec"
	"strings"
	"github.com/apex/log"
	"github.com/google/shlex"
	"github.com/ooni/probe-engine/model"
)
type runconfig struct {
	args     []string
	loginfof func(format string, v ...interface{})
	name     string
	stdout   *os.File
	stderr   *os.File
}
func run(config runconfig) error {
	config.loginfof("exec: %s %s", config.name, strings.Join(config.args, " "))
	cmd := exec.Command(config.name, config.args...)
	cmd.Stdout = config.stdout
	cmd.Stderr = config.stderr
	err := cmd.Run()
	config.loginfof("exec result: %+v", err)
	return err
}
func Run(name string, arg ...string) error {
	return run(runconfig{
		args:     arg,
		loginfof: log.Log.Infof,
		name:     name,
		stdout:   os.Stdout,
		stderr:   os.Stderr,
	})
}
func RunQuiet(name string, arg ...string) error {
	return run(runconfig{
		args:     arg,
		loginfof: model.DiscardLogger.Infof,
		name:     name,
		stdout:   nil,
		stderr:   nil,
	})
}