在 Go 语言中使用 exec 包执行 Shell 命令(上)

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

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
相关文章
|
4天前
|
Shell 程序员 数据安全/隐私保护
shell 脚本 if-else判断 和流程控制 (基本语法|基础命令)
shell 脚本 if-else判断 和流程控制 (基本语法|基础命令)
|
10天前
|
安全 测试技术 Go
Golang深入浅出之-Go语言单元测试与基准测试:testing包详解
【4月更文挑战第27天】Go语言的`testing`包是单元测试和基准测试的核心,简化了测试流程并鼓励编写高质量测试代码。本文介绍了测试文件命名规范、常用断言方法,以及如何进行基准测试。同时,讨论了测试中常见的问题,如状态干扰、并发同步、依赖外部服务和测试覆盖率低,并提出了相应的避免策略,包括使用`t.Cleanup`、`t.Parallel()`、模拟对象和检查覆盖率。良好的测试实践能提升代码质量和项目稳定性。
16 1
|
10天前
|
安全 Go
Golang深入浅出之-Go语言标准库中的文件读写:io/ioutil包
【4月更文挑战第27天】Go语言的`io/ioutil`包提供简单文件读写,适合小文件操作。本文聚焦`ReadFile`和`WriteFile`函数,讨论错误处理、文件权限、大文件处理和编码问题。避免错误的关键在于检查错误、设置合适权限、采用流式读写及处理编码。遵循这些最佳实践能提升代码稳定性。
20 0
|
10天前
|
缓存 编译器 Go
【Go语言专栏】理解Go语言的包管理机制
【4月更文挑战第30天】Go语言包管理是构建可维护应用的关键,从基本概念如包导入、初始化到版本管理和依赖管理,再到Go Modules的引入,简化了过程。包的可见性规则和社区生态也至关重要。理解并掌握这些机制对于编写高质量Go代码具有决定性影响。随着Go语言的持续发展,包管理将更加强大易用。
|
11天前
|
安全 Unix Go
Golang深入浅出之-Go语言中的时间与日期处理:time包详解
【4月更文挑战第26天】Go语言的`time`包提供处理日期和时间的功能,包括`time.Time`类型、时间戳、格式化与解析。本文讨论了核心概念、常见问题(如时区处理、格式字符串混淆、超时控制和并发安全)及解决方法。推荐使用`time.LoadLocation`管理时区,熟悉时间格式规则,用`context`精确控制超时,并注意并发安全。文中通过代码示例展示了如何获取格式化时间、计算时间差以及创建定时任务。学习和应用这些知识可提高程序的健壮性和准确性。
27 2
|
11天前
|
XML JSON Go
Golang深入浅出之-XML处理在Go语言中的实现:encoding/xml包
【4月更文挑战第26天】Go语言的`encoding/xml`库提供XML处理,包括序列化和反序列化。本文讨论了XML处理的基础,如`xml.Marshal`和`xml.Unmarshal`函数,以及常见问题和易错点,如标签命名、结构体嵌套、omitempty标签和命名空间。建议遵循标签命名规则,正确处理嵌套和属性,谨慎使用omitempty,以及理解并有效利用命名空间。文中还给出了基础示例和处理XML属性的代码示例,帮助读者掌握XML处理技巧。
22 1
Golang深入浅出之-XML处理在Go语言中的实现:encoding/xml包
|
12天前
|
数据管理 Go 开发者
Golang深入浅出之-Go语言上下文(context)包:处理取消与超时
【4月更文挑战第25天】Go语言中的`context`包在并发、网络请求和长任务中至关重要,提供取消、截止时间和元数据管理。本文探讨`context`基础,如`Background()`、`TODO()`、`WithCancel()`、`WithDeadline()`和`WithTimeout()`。常见问题包括不当传递、过度使用`Background()`和`TODO()`以及忽略错误处理。通过取消和超时示例,强调正确传递上下文、处理取消错误和设置超时以提高应用健壮性和响应性。正确使用`context`是构建稳定高效Go应用的关键。
21 1
|
14天前
|
Go 开发者
Golang深入浅出之-Go语言上下文(context)包:处理取消与超时
【4月更文挑战第23天】Go语言的`context`包提供`Context`接口用于处理任务取消、超时和截止日期。通过传递`Context`对象,开发者能轻松实现复杂控制流。本文解析`context`包特性,讨论常见问题和解决方案,并给出代码示例。关键点包括:1) 确保将`Context`传递给所有相关任务;2) 根据需求选择适当的`Context`创建函数;3) 定期检查`Done()`通道以响应取消请求。正确使用`context`包能提升Go程序的控制流管理效率。
21 1
|
14天前
|
存储 安全 Go
Golang深入浅出之-原子操作包(sync/atomic)在Go中的应用
【4月更文挑战第23天】Go语言的`sync/atomic`包支持原子操作,防止多线程环境中的数据竞争。包括原子整数和指针操作,以及原子标量函数。常见问题包括误用非原子操作、误解原子操作语义和忽略内存排序约束。解决方法是使用原子函数、结合其他同步原语和遵循内存约束。注意始终使用原子操作处理共享变量,理解其语义限制,并熟悉内存排序约束,以实现并发安全和高效的应用程序。
25 1
|
16天前
|
网络协议 Unix Shell
第十一章 Shell常用命令与工具(二)
第十一章 Shell常用命令与工具(二)