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各时间字符串使用解析
Apr 02 Golang
go原生库的中bytes.Buffer用法
Apr 25 Golang
golang通过递归遍历生成树状结构的操作
Apr 28 Golang
golang goroutine顺序输出方式
Apr 29 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
go类型转换及与C的类型转换方式
May 05 Golang
Golang 编译成DLL文件的操作
May 06 Golang
goland 设置project gopath的操作
May 06 Golang
Goland使用Go Modules创建/管理项目的操作
May 06 Golang
go语言基础 seek光标位置os包的使用
May 09 Golang
Golang 结构体数据集合
Apr 22 Golang
go goth封装第三方认证库示例详解
Aug 14 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中计算未知长度的字符串哪个字符出现的次数最多的代码
2012/08/14 PHP
php5.3 不支持 session_register() 此函数已启用的解决方法
2013/11/12 PHP
PHP判断上传文件类型的解决办法
2015/10/20 PHP
php防止sql注入的方法详解
2017/02/20 PHP
PHP实现上传多图即时显示与即时删除的方法
2017/05/09 PHP
PHP程序员简单的开展服务治理架构操作详解(二)
2020/05/14 PHP
js下用gb2312编码解码实现方法
2009/12/31 Javascript
通过jquery的$.getJSON做一个跨域ajax请求试验
2011/05/03 Javascript
JS代码优化技巧之通俗版(减少js体积)
2011/12/23 Javascript
addEventListener和attachEvent二者绑定的执行函数中的this不相同
2012/12/09 Javascript
Jquery chosen动态设置值实例介绍
2013/08/08 Javascript
DOM操作一些常用的属性汇总
2015/03/13 Javascript
JavaScript中的acos()方法使用详解
2015/06/14 Javascript
EditPlus中的正则表达式 实战(2)
2016/12/15 Javascript
bootstrap table分页模板和获取表中的ID方法
2017/01/10 Javascript
js实现横向拖拽导航条功能
2017/02/17 Javascript
jQuery插件echarts实现的去掉X轴、Y轴和网格线效果示例【附demo源码下载】
2017/03/04 Javascript
vue-cli + sass 的正确打开方式图文详解
2017/10/27 Javascript
vue2.0 移动端实现下拉刷新和上拉加载更多的示例
2018/04/23 Javascript
移动端吸顶fixbar的解决方案详解
2019/07/17 Javascript
JavaScript复制变量三种方法实例详解
2020/01/09 Javascript
[58:09]Spirit vs NB Supermajor小组赛 A组败者组决赛 BO3 第三场 6.2
2018/06/03 DOTA
python抓取京东商城手机列表url实例代码
2013/12/18 Python
python数据结构之二叉树的统计与转换实例
2014/04/29 Python
Python数据结构与算法之常见的分配排序法示例【桶排序与基数排序】
2017/12/15 Python
Python实现的银行系统模拟程序完整案例
2019/04/12 Python
pyqt5 QScrollArea设置在自定义侧(任何位置)
2019/09/25 Python
史上最详细的Python打包成exe文件教程
2021/01/17 Python
详解css3 mask遮罩实现一些特效
2018/10/24 HTML / CSS
PatPat阿根廷:妈妈们的购物平台
2019/05/30 全球购物
日本即尚网:JSHOPPERS.com(支持中文)
2019/12/03 全球购物
消防安全责任书
2014/04/14 职场文书
教师三严三实对照检查材料
2014/09/25 职场文书
预备党员转正思想汇报
2014/09/26 职场文书
2015年学生会纪检部工作总结
2015/03/31 职场文书
创作书写之导游词实用技巧分享(干货)
2019/12/20 职场文书