微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

golang exec.Command 执行命令用法实例

目录

cmd字段介绍

用法一:直接在当前目录使用并返回结果

用法二:在命令位置使用并返回结果

用法三:在命令位置使用并实时输出每行结果

用法四:在命令位置使用并实时写入每行结果到文件

用法五:bash -c 方式执行


cmd字段介绍

type Cmd struct {  
    Path         string   //运行命令的路径,绝对路径或者相对路径  
    Args         []string   // 命令参数  
    Env          []string         //进程环境,如果环境为空,则使用当前进程的环境  
    Dir          string   //指定command的工作目录,如果dir为空,则comman在调用进程所在当前目录中运行  
    Stdin        io.Reader  //标准输入,如果stdin是nil的话,进程从null device中读取(os.DevNull),stdin也可以时一个文件,否则的话则在运行过程中再开一个goroutine去  
             //读取标准输入  
    Stdout       io.Writer       //标准输出  
    Stderr       io.Writer  //错误输出,如果这两个(Stdout和Stderr)为空的话,则command运行时将响应的文件描述符连接到os.DevNull  
    ExtraFiles   []*os.File     
    SysProcAttr  *syscall.SysProcAttr  
    Process      *os.Process    //Process是底层进程,只启动一次  
    Processstate *os.Processstate  //Processstate包含一个退出进程的信息,当进程调用Wait或者Run时便会产生该信息.  
}  

用法一:直接在当前目录使用并返回结果

func Cmd(commandName string,params []string) (string,error) {
    cmd := exec.Command(commandName,params...)
    fmt.Println("Cmd",cmd.Args)
    var out bytes.Buffer
    cmd.Stdout = &out
    cmd.Stderr = os.Stderr
    err := cmd.Start()
    if err != nil {
        return "",err
    }
    err = cmd.Wait()
    return out.String(),err
}

用法二:在命令位置使用并返回结果

func CmdAndChangeDir(dir string,commandName string,params...)
    fmt.Println("CmdAndChangeDir",dir,cmd.Args)
    var out bytes.Buffer
    cmd.Stdout = &out
    cmd.Stderr = os.Stderr
    cmd.Dir = dir
    err := cmd.Start()
    if err != nil {
        return "",err
}

用法三:在命令位置使用并实时输出每行结果

func CmdAndChangeDirToShow(dir string,params []string) error {
  cmd := exec.Command(commandName,params...)
  fmt.Println("CmdAndChangeDirToFile",cmd.Args)
  //StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。
  stdout,err := cmd.StdoutPipe()
  if err != nil {
    fmt.Println("cmd.StdoutPipe: ",err)
    return err
  }
  cmd.Stderr = os.Stderr
  cmd.Dir = dir
  err = cmd.Start()
  if err != nil {
    return err
  }
  //创建一个流来读取管道内内容,这里逻辑是通过一行一行的读取的
  reader := bufio.NewReader(stdout)
  //实时循环读取输出流中的一行内容
  for {
    line,err2 := reader.ReadString('\n')
    if err2 != nil || io.EOF == err2 {
      break
    }
    fmt.Println(line)
  }
  err = cmd.Wait()
  return err
}

用法四:在命令位置使用并实时写入每行结果到文件

func CmdAndChangeDirToFile(fileName,params []string) error {
    Path,err := GetCurrentPath()
    if err != nil {
        return err
    }
    Path += "logs/cmdDir/"
    EnsureDir(Path)
    f,err := os.Create(Path + fileName) //创建文件
    defer f.Close()
    cmd := exec.Command(commandName,params...)
    fmt.Println("CmdAndChangeDirToFile",cmd.Args)
    //StdoutPipe方法返回一个在命令Start后与命令标准输出关联的管道。Wait方法获知命令结束后会关闭这个管道,一般不需要显式的关闭该管道。
    stdout,err := cmd.StdoutPipe()
    if err != nil {
        fmt.Println("cmd.StdoutPipe: ",err)
        return err
    }
    cmd.Stderr = os.Stderr
    cmd.Dir = dir
    err = cmd.Start()
    if err != nil {
        return err
    }
    //创建一个流来读取管道内内容,这里逻辑是通过一行一行的读取的
    reader := bufio.NewReader(stdout)
    //实时循环读取输出流中的一行内容
    for {
        line,err2 := reader.ReadString('\n')
        if err2 != nil || io.EOF == err2 {
            break
        }
        _,err = f.WriteString(line) //写入文件(字节数组)
        f.Sync()
    }
    _,err = f.WriteString("=================处理完毕========================") //写入文件(字节数组)
    f.Sync()
    err = cmd.Wait()
    return err
}

用法五:bash -c 方式执行

// 后台运行一个命令 bash -c 方式
func CmdBash(commandName string) *exec.Cmd {
	cmd := exec.Command("/bin/bash","-c",commandName)
	fmt.Println(line)(cmd.Args)

	go func() {
		var out bytes.Buffer
		cmd.Stdout = &out
		cmd.Stderr = os.Stderr
		_ = cmd.Run()
	}()

	return cmd
}

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐