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 相关文章推荐
Go语言使用select{}阻塞main函数介绍
Apr 25 Golang
go语言中切片与内存复制 memcpy 的实现操作
Apr 27 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
解决goland 导入项目后import里的包报红问题
May 06 Golang
go语言中http超时引发的事故解决
Jun 02 Golang
go语言使用Casbin实现角色的权限控制
Jun 26 Golang
Golang 语言控制并发 Goroutine的方法
Jun 30 Golang
golang fmt格式“占位符”的实例用法详解
Jul 04 Golang
基于Go语言构建RESTful API服务
Jul 25 Golang
修改并编译golang源码的操作步骤
Jul 25 Golang
go使用Gin框架利用阿里云实现短信验证码功能
Aug 04 Golang
GO中sync包自由控制并发示例详解
Aug 05 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-fpm的配置详解
2013/06/03 PHP
PHP中IP地址与整型数字互相转换详解
2014/08/20 PHP
Laravel创建数据库表结构的例子
2019/10/09 PHP
jquery each()源代码
2011/02/14 Javascript
Jquery ajax传递复杂参数给WebService的实现代码
2011/08/08 Javascript
JS小功能(offsetLeft实现图片滚动效果)实例代码
2013/11/28 Javascript
JS实现黑客帝国文字下落效果
2015/09/01 Javascript
学习JavaScript设计模式之装饰者模式
2016/01/19 Javascript
JS脚本实现动态给标签控件添加事件的方法
2016/06/02 Javascript
Vue.js实现模拟微信朋友圈开发demo
2017/04/20 Javascript
如何理解Vue的render函数的具体用法
2017/08/30 Javascript
Angular中点击li标签实现更改颜色的核心代码
2017/12/08 Javascript
浅谈webpack打包生成的bundle.js文件过大的问题
2018/02/22 Javascript
改变vue请求过来的数据中的某一项值的方法(详解)
2018/03/08 Javascript
微信小程序登录换取token的教程
2018/05/31 Javascript
Vue render渲染时间戳转时间,时间转时间戳及渲染进度条效果
2018/07/27 Javascript
JavaScript正则表达式验证登录实例
2020/03/18 Javascript
使用typescript快速开发一个cli的实现示例
2020/12/09 Javascript
[49:15]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第二场 1月19日
2021/03/11 DOTA
10个Python小技巧你值得拥有
2018/09/29 Python
OpenCV-Python 摄像头实时检测人脸代码实例
2019/04/30 Python
python 缺失值处理的方法(Imputation)
2019/07/02 Python
pandas将多个dataframe以多个sheet的形式保存到一个excel文件中
2019/10/10 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
pytorch模型预测结果与ndarray互转方式
2020/01/15 Python
Python 使用SFTP和FTP实现对服务器的文件下载功能
2020/12/17 Python
html5中localStorage本地存储的简单使用
2017/06/16 HTML / CSS
HTML5拖放API实现拖放排序的实例代码
2017/05/11 HTML / CSS
英国办公用品商店:Office Outlet
2018/04/04 全球购物
苏格兰在线威士忌商店:The Whisky Barrel
2019/05/07 全球购物
俄罗斯香水在线商店:AromaCode
2019/12/04 全球购物
英国第一的滑雪服装和装备零售商:Snow+Rock
2020/02/01 全球购物
小组名称和口号
2014/06/09 职场文书
物业项目经理岗位职责
2015/04/01 职场文书
公司要求试用期员工提交“述职报告”,该怎么写?
2019/07/17 职场文书
解决golang结构体tag编译错误的问题
2021/05/02 Golang