1. 前言
有时候我们需要在go程序中调用外部命令,本文通过精心设计的案例来演示如何使用exec
包实现这一功能。
本文代码在Linux系统中运行正常,并未在windows系统中测试过(不一定适用于windows系统),你可以参考本文的示例代码创建对应的windows版本。
2. 示例1:调用vi 和 cat 命令
示例1的功能如下图所示:
2.1 代码
package main
import (
"log"
"os"
"os/exec"
"fmt"
)
func main() {
// 1 Read filename from stdin
var file string
fmt.Print("Enter filename: ")
_, err := fmt.Scanln(&file)
if err != nil {
log.Fatalf("failed to read filename: %v", err)
}
// 2 Create/edit the file using vi editor
fmt.Printf("> vi %s\n", file)
cmd := exec.Command("vi", file)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
log.Fatalf("vi %q: %v", file, err)
}
// 3 Print the content of the file using cat command
fmt.Printf("> cat %s\n", file)
cmd = exec.Command("cat", file)
out, err := cmd.Output()
if err != nil {
log.Fatalf("cat %q: %v", file, err)
}
fmt.Println(string(out))
}
代码说明
- 1 使用
fmt.Scanln
函数,从标准输入设备读取文件名, 如 demo.txt. - 2 调用外部命令
vi
编辑 demo.txt。 这一步首先使用exec.Command("vi", file)
得到一个*Cmd
, 然后绑定其 Stdin/Stdout/Stderr至 os.Stdin/os.Stdout/os.Stderr,最后调用cmd.Run()
执行外部命令vi
. - 3 调用外部命令 cat 显示 demo.txt 文件的内容. 这一步中的
cmd.Output()
用于捕捉外部命令的标准输出.
2.2 示例1演示
3. 示例2: 调用python解释器求值算术表达式
本示例要求电脑上已经安装
Python3
示例2的功能如下图所示:
3.1 代码
package main
import (
"log"
"os/exec"
"fmt"
)
func main() {
// 1 Read filename from stdin
var expr string
fmt.Print("Enter an arithmetic expression: ")
_, err := fmt.Scanln(&expr)
if err != nil {
log.Fatalf("failed to read an expression: %v", err)
}
// 2 Create an executable python script
script := fmt.Sprintf("print(eval('%s'))", expr)
// 3 Evaluate the expression by invoking a python command
cmd := exec.Command("python3", "-c", script)
out, err := cmd.Output()
if err != nil {
log.Fatalf("failed to evaluate expression: %v", err)
}
fmt.Printf("%s = %s", expr, string(out))
}
示例2的代码与示例1有诸多相似之处,在此不再赘述。
3.2 示例2演示
4. 结束语
本文通过两个实用示例并配以图文,介绍了go语言中如何调用外部命令。
关于exec
包的详细说明,请参阅其官方文档.