Golang exec.Command


原文链接: Golang exec.Command

go 调用shell命令 两种方式(有无返回值) - 风逸者儿的博客 - CSDN博客

// 封装 git 命令
func git(args ...string) (string, error) {
	cmd := exec.Command("git", args...)
	out, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("git failed: %q: %q (%q)", err, out, args)
	}
	return string(out), nil
}

func tagExists(tag string) (bool, error) {
	out, err := git("tag", "-l", tag)

	if err != nil {
		return false, err
	}
	if strings.Contains(out, tag) {
		return true, nil
	}
	return false, nil
}
  1. 阻塞方式(需要执行结果)等待执行完统一返回执行结果
    适用于执行普通非阻塞shell命令,且需要shell标准输出的
    需要对shell标准输出的逐行实时进行处理的

  2. 实时输出执行结果

    func execCommand(commandName string, params []string) bool {
    //函数返回一个*Cmd,用于使用给出的参数执行name指定的程序
    cmd := exec.Command(commandName, params...)
    
    //显示运行的命令
    fmt.Println(cmd.Args)
    //StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。
    stdout, err := cmd.StdoutPipe()
    
    if err != nil {
        fmt.Println(err)
        return false
    }
    
    cmd.Start()
    //创建一个流来读取管道内内容,这里逻辑是通过一行一行的读取的
    reader := bufio.NewReader(stdout)
    
    //实时循环读取输出流中的一行内容
    for {
        line, err2 := reader.ReadString('\n')
        if err2 != nil || io.EOF == err2 {
            break
        }
        fmt.Println(line)
    }
    
    //阻塞直到该命令执行完成,该命令必须是被Start方法开始执行的
    cmd.Wait()
    return true
    }
    
    1. 非阻塞方式(不需要执行结果) 用于调用服务器死循环,且不需要返回结果的
      go //不需要执行命令的结果与成功与否,执行命令马上就返回 func Run(command string) { //处理启动参数,通过空格分离 如:setsid /home/luojing/gotest/src/test_main/iwatch/test/while_little & command_name_and_args := strings.FieldsFunc(command, splite_command) //开始执行c包含的命令,但并不会等待该命令完成即返回 cmd.Start() if err != nil { fmt.Printf("%v: exec command:%v error:%v\n", get_time(), command, err) } fmt.Printf("Waiting for command:%v to finish...\n", command) //阻塞等待fork出的子进程执行的结果,和cmd.Start()配合使用[不等待回收资源,会导致fork出执行shell命令的子进程变为僵尸进程] err = cmd.Wait() if err != nil { fmt.Printf("%v: Command finished with error: %v\n", get_time(), err) } return }

官网的标准中文库

mysql 导入数据

FYI, exec.Command doesn't use the shell and the redirection is a function of the shell.
So < /goserver.sql will not work.
To use the redirection, pass your commands to the shell.

cmd := exec.Command("sh", "-c", "mysql -uroot -proot mjolnir_dev < /goserver.sql")
err := cmd.Run()
cmd := exec.Command("/usr/local/mysql/bin/mysql", "-h127.0.0.1", "-P3333", 
  "-uusr", "-pPassxxx", "-Ddtb_test",
  "-e", "source /Users/XXX/Documents/test/scripts/olds/SCRIPT_XXX.sql")
  1. using golang
    ```go
    file, err := ioutil.ReadAll("/path/to/file")

if err != nil {

// handle error

}

requests := strings.Split(string(file), ";")

for _, request := range requests {

result, err := db.Exec(request)
// do whatever you need with result and error

}
```

`