Go语言入门exec的基本使用


Posted in Golang onMay 20, 2022

Exec 是 os 包中的一个子包,它可用于使用 Go 运行外部命令。Go exec 命令教程展示了如何在 Golang 中执行 shell 命令和程序。

要使用这个包,我们需要按如下方式导入:

import "os/exec"

使用 GoLang exec 包运行命令

我们可以运行任何我们希望的命令。就像我们使用 CMD、bash 或其他一些 shell 来运行命令一样,它可以运行这些命令。

这是运行 ls 命令的示例。新建一个 main.go :

package main
import (
  "fmt"
  "os/exec"
)
func main() {
  cmd := exec.Command("ls")
  e := cmd.Run()
  CheckError(e)
}
func CheckError(e error) {
  if e != nil {
    fmt.Println(e)
  }
}

Run 函数启动指定命令并等待它完成,而 Start 启动指定命令但不等待它完成;我们需要使用Wait with Start。

然后新建一个 go.mod 文件:

$ go mod init main.go
go: creating new go.mod: module main.go
go: to add module requirements and sums:
  go mod tidy

现在,程序将运行,但我们不会看到控制台的任何输出。原因是命令运行,输出没有发送到标准输出。

$ go run main.go

所以,我们需要修复它。添加下面显示的两行以查看控制台的任何输出。

cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr

输出将显示当前目录中的文件。

package main
import (
  "fmt"
  "os"
  "os/exec"
)
func main() {
  cmd := exec.Command("ls", "-lah")
  cmd.Stdout = os.Stdout
  cmd.Stderr = os.Stderr
  e := cmd.Run()
  CheckError(e)
}
func CheckError(e error) {
  if e != nil {
    fmt.Println(e)
  }
}

然后我们再程序,可以看到标准台输出如下的文件:

$ go run main.go
total 16
drwxr-xr-x   4 yuzhou_1su  staff   128B  5 15 22:56 .
drwxr-xr-x  23 yuzhou_1su  staff   736B  5 15 22:53 ..
-rw-r--r--   1 yuzhou_1su  staff    24B  5 15 22:56 go.mod
-rw-r--r--   1 yuzhou_1su  staff   248B  5 15 23:18 main.go

利用直接 ls 直接运行该命令,可以看到结果正确:

$ ls -alh
total 16
drwxr-xr-x   4 yuzhou_1su  staff   128B  5 15 22:56 .
drwxr-xr-x  23 yuzhou_1su  staff   736B  5 15 22:53 ..
-rw-r--r--   1 yuzhou_1su  staff    24B  5 15 22:56 go.mod
-rw-r--r--   1 yuzhou_1su  staff   248B  5 15 23:18 main.go

为不同的操作系统指定命令

我们可以指定针对不同操作系统运行不同的命令(例如 Linux 上的 bash 命令)。这是一个例子。

if runtime.GOOS == "linux" {
    cmd = exec.Command("ls")
}

为此,我们还需要导入运行时包。

要查看所有可能的操作系统,我们可以运行 go tool dist list ,它将显示所有可能的操作系统和 ARCH 组合。

Go exec 命令捕获输出

输出运行命令并返回其标准输出:

package main
import (
    "fmt"
    "log"
    "os/exec"
)
func main() {
    out, err := exec.Command("ls", "-l").Output()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(string(out))
}

运行该程序:

$ go run main.go
total 16
-rw-r--r--  1 yuzhou_1su  staff   24  5 15 22:56 go.mod
-rw-r--r--  1 yuzhou_1su  staff  180  5 15 23:33 main.go

Go cmd.StdinPipe

管道允许我们将一个命令的输出发送到另一个命令。 StdinPipe 返回一个管道,该管道将在命令启动时连接到命令的标准输入。

package main
import (
    "fmt"
    "io"
    "log"
    "os/exec"
)
func main() {
    cmd := exec.Command("cat")
    stdin, err := cmd.StdinPipe()
    if err != nil {
        log.Fatal(err)
    }
    go func() {
        defer stdin.Close()
        io.WriteString(stdin, "an old falcon")
    }()
    out, err := cmd.CombinedOutput()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s\n", out)
}

在代码示例中,我们将字符串写入 goroutine 内的标准输入。

cmd := exec.Command("cat")

cat 命令将给定的文件连接到标准输出。当没有给定文件或带有 - 时,该命令读取标准输入并将其打印到标准输出。

stdin, err := cmd.StdinPipe()

我们得到 cat 命令的标准输入管道。

go func() {
    defer stdin.Close()
    io.WriteString(stdin, "an old falcon")
}()

在 goroutine 内部,我们将一个字符串写入标准输入管道。

$ go run stdinpipe.go 
an old falcon

Go cmd.StdoutPipe

StdoutPipe 返回一个管道,该管道将在命令启动时连接到命令的标准输出。

package main
import (
    "fmt"
    "io/ioutil"
    "log"
    "os/exec"
    "strings"
)
func upper(data string) string {
    return strings.ToUpper(data)
}
func main() {
    cmd := exec.Command("echo", "an old falcon")
    stdout, err := cmd.StdoutPipe()
    if err != nil {
        log.Fatal(err)
    }
    if err := cmd.Start(); err != nil {
        log.Fatal(err)
    }
    data, err := ioutil.ReadAll(stdout)
    if err != nil {
        log.Fatal(err)
    }
    if err := cmd.Wait(); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("%s\n", upper(string(data)))
}

该示例通过管道读取 echo 命令的输出并将其转换为大写字母。

cmd := exec.Command("echo", "an old falcon")

要运行的命令是带有单个字符串参数的 echo 命令。

stdout, err := cmd.StdoutPipe()

我们得到标准输出管道。

if err := cmd.Start(); err != nil {
    log.Fatal(err)
}

该命令使用 Start 函数执行;它不会等待它完成。

data, err := ioutil.ReadAll(stdout)

我们从管道中读取数据。

if err := cmd.Wait(); err != nil {
    log.Fatal(err)
}

Wait 等待命令退出并等待任何复制到 stdin 或从 stdout 或 stderr 复制完成。它在看到命令退出后关闭管道。

运行该程序:

$ go run stdoutpipe.go 
AN OLD FALCON

总结

os/exec 包运行外部命令。它包装了 os.StartProcess 以便更轻松地重新映射标准输入和标准输出、将 I/O 与管道连接以及进行其他调整。

参考链接:

https://zetcode.com/golang/exec-command/

以上就是Go语言入门exec的基本使用示例的详细内容!


Tags in this post...

Golang 相关文章推荐
golang判断key是否在map中的代码
Apr 24 Golang
Golang 实现超大文件读取的两种方法
Apr 27 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
go mod 安装依赖 unkown revision问题的解决方案
May 06 Golang
GoLang中生成UUID唯一标识的实现
May 08 Golang
如何利用golang运用mysql数据库
Mar 13 Golang
Go 中的空白标识符下划线
Mar 25 Golang
golang使用map实现去除重复数组
Apr 14 Golang
golang语言指针操作
Apr 14 Golang
GO语言字符串处理函数之处理Strings包
Apr 14 Golang
Golang实现可重入锁的示例代码
May 25 Golang
详解Go语言中Get/Post请求测试
Jun 01 Golang
Golang并发工具Singleflight
May 06 #Golang
深入理解 Golang 的字符串
May 04 #Golang
Golang入门之计时器
May 04 #Golang
Golang 入门 之url 包
May 04 #Golang
Golang解析JSON对象
Apr 30 #Golang
Golang 并发编程 SingleFlight模式
Golang 实现 WebSockets 之创建 WebSockets
Apr 24 #Golang
You might like
PHP中str_replace函数使用小结
2008/10/11 PHP
基于php伪静态的实现详细介绍
2013/04/28 PHP
PHP session文件独占锁引起阻塞问题解决方法
2015/05/12 PHP
win10环境PHP 7 安装配置【教程】
2016/05/09 PHP
360搜索引擎自动收录php改写方案
2018/04/28 PHP
制作特殊字的脚本
2006/06/26 Javascript
javascript 获取元素位置的快速方法 getBoundingClientRect()
2009/11/26 Javascript
同时使用n个window onload加载实例介绍
2013/04/25 Javascript
使用js正则控制input标签只允许输入的值
2013/07/29 Javascript
js登录弹出层特效
2014/03/07 Javascript
Javascript this 关键字 详解
2014/10/22 Javascript
Node.js开发之访问Redis数据库教程
2015/01/14 Javascript
使用jquery 简单实现下拉菜单
2015/01/14 Javascript
innerHTML属性,outerHTML属性,textContent属性,innerText属性区别详解
2015/03/13 Javascript
JavaScript实现为指定对象添加多个事件处理程序的方法
2015/04/17 Javascript
AngularJS基础学习笔记之表达式
2015/05/10 Javascript
最新最热最实用的15个jQuery插件汇总
2015/07/05 Javascript
实例代码讲解jquery easyui动态tab页
2015/11/17 Javascript
Vue.js实现文章评论和回复评论功能
2020/05/30 Javascript
详解微信小程序 通过控制CSS实现view隐藏与显示
2017/05/24 Javascript
ES6知识点整理之对象解构赋值应用示例
2019/04/17 Javascript
小程序实现左滑删除效果
2019/07/25 Javascript
vue自定义指令限制输入框输入值的步骤与完整代码
2020/08/30 Javascript
JavaScript 如何在浏览器中使用摄像头
2020/12/02 Javascript
浅谈python中拼接路径os.path.join斜杠的问题
2018/10/23 Python
tensorflow之自定义神经网络层实例
2020/02/07 Python
软件设计的目标是什么
2016/12/04 面试题
vue+django实现下载文件的示例
2021/03/24 Vue.js
在校生党员自我评价
2013/09/25 职场文书
学生打架检讨书大全
2014/01/23 职场文书
圣诞节红领巾广播稿
2014/02/03 职场文书
优秀高中生事迹材料
2014/02/11 职场文书
妇联主席先进事迹
2014/05/18 职场文书
活动宣传稿范文
2015/07/23 职场文书
nginx限制并发连接请求数的方法
2021/04/01 Servers
django学习之ajax post传参的2种格式实例
2021/05/14 Python