像 python-sh 一样,可以轻松使用 golang 调用 shell .
使用介绍
Go 标准库有 os/exec 也可以执行 shell ,不过用起来并不顺手, go-sh 和它非常相似。不过,go-sh 提供了更好的开发体验。 官方 GitHub。
Pipe 示例:
1
2
3
4
5
6
7
8
|
package main
import "github.com/codeskyblue/go-sh"
func main() {
sh.Command("echo", "hello\tworld").Command("cut", "-f2").Run()
}
|
这是它的以下特性:
-
保持环境变量(比如 export)
-
支持别名 (例如 shell 中的别名)
-
记住当前的目录
-
管道命令
-
内置 shell 命令 echo 和 test
-
timeout 支持
使用示例
比较常用的使用场景。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
sh: echo hello
go: sh.Command("echo", "hello").Run()
sh: export BUILD_ID=123
go: s = sh.NewSession().SetEnv("BUILD_ID", "123")
sh: alias ll='ls -l'
go: s = sh.NewSession().Alias('ll', 'ls', '-l')
sh: (cd /; pwd)
go: sh.Command("pwd", sh.Dir("/")).Run()
sh: test -d data || mkdir data
go: if ! sh.Test("dir", "data") { sh.Command("mkdir", "data").Run() }
sh: cat first second | awk '{print $1}'
go: sh.Command("cat", "first", "second").Command("awk", "{print $1}").Run()
sh: count=$(echo "one two three" | wc -w)
go: count, err := sh.Echo("one two three").Command("wc", "-w").Output()
sh(in ubuntu): timeout 1s sleep 3
go: c := sh.Command("sleep", "3"); c.Start(); c.WaitTimeout(time.Second) # default SIGKILL
go: out, err := sh.Command("sleep", "3").SetTimeout(time.Second).Output() # set session timeout and get output)
sh: echo hello | cat
go: out, err := sh.Command("cat").SetInput("hello").Output()
sh: cat # read from stdin
go: out, err := sh.Command("cat").SetStdin(os.Stdin).Output()
sh: ls -l > /tmp/listing.txt # write stdout to file
go: err := sh.Command("ls", "-l").WriteStdout("/tmp/listing.txt")
|
如果需要保持环境变量和工作目录,可以创建 session 来实现。
1
2
3
4
5
6
7
8
9
|
session := sh.NewSession()
session.SetEnv("BUILD_ID", "123")
session.SetDir("/")
# then call cmd
session.Command("echo", "hello").Run()
# set ShowCMD to true for easily debug
session.ShowCMD = true
|
如果使用管道,默认情况下,只有在管道最后一个环节命令退出状态不为 0 的情况,才任务命令失败,如果想要在执行管道的过程中,其中一个环节出现命令退出状态不为 0 就抛出错误的话,需要设置 pipefail 属性为 true 来实现。
1
2
3
|
session := sh.NewSession()
session.PipeFail = true
session.Command("cat", "unknown-file").Command("echo").Run()
|
同样的,想要捕获整个执行过程中所有环节的 stderr ,也需要设置参数来启用,设置 session.PipeStdErrors = true
即可。