go run linux cmd,gocommand:一个跨平台的golang命令行执行package

博客介绍了如何在Go语言中封装exec.Command,创建了一个名为gocommand的库,用于简化在Linux和Windows系统下执行shell命令或调用第三方程序。该库提供了Exec、ExecAsync和ExecIgnoreResult等接口,分别用于同步执行命令并获取结果、异步执行命令以及忽略结果的执行。示例代码展示了如何使用这个库,并提到了对其他平台的支持可以由社区贡献。
摘要由CSDN通过智能技术生成

最近在做一个项目的时候,需要使用golang来调用操作系统中的命令行,来执行shell命令或者直接调用第三方程序,这其中自然就用到了golang自带的exec.Command.

但是如果直接使用原生exec.Command会造成大量的重复代码,网上搜了一圈又没有找到对exec.Command相应的封装包,索性自己封装了一个,取名为gocommand.目前支持Linux和Windows,欢迎各位大神在github上提交代码补充其他平台的实现.

下面介绍一下gocommand库的实现思路:package gocommand // 命令行接口type Commanderinterface {// 执行命令行并返回结果// args: 命令行参数// return: 进程的pid, 命令行结果, 错误消息Exec(args ...string) (int, string, error) // 异步执行命令行并通过channel返回结果// stdout: chan结果// args: 命令行参数// return: 进程的pid// exception: 协程内的命令行发生错误时,会panic异常ExecAsync(stdoutchan string, args ...string) int // 执行命令行(忽略返回值)// args: 命令行参数// return: 错误消息ExecIgnoreResult(args ...string) error}

gocommand目前的命令行执行函数都是源于Commander接口,目前该接口定义了3个函数,分别是:执行命令行病返回结果;异步执行命令行并得到结果;执行命令行并忽略结果.package gocommand import ("runtime") // Command的初始化函数func NewCommand() Commander {var cmd Commander switch runtime.GOOS {case "linux":cmd = NewLinuxCommand()case "windows":cmd = NewWindowsCommand()default:cmd = NewLinuxCommand()} return cmd}

创建一个Command的实现,并根据当前的操作系统,返回对应的实现函数,目前只实现了Linux和Windows,(Mac留给各位大神(土豪)了),其中LinuxCommand的代码实现如下:package gocommand import ("io/ioutil""os""os/exec""syscall") // LinuxCommand结构体type LinuxCommandstruct {} // LinuxCommand的初始化函数func NewLinuxCommand() *LinuxCommand {return &LinuxCommand{}} // 执行命令行并返回结果// args: 命令行参数// return: 进程的pid, 命令行结果, 错误消息func (lc *LinuxCommand) Exec(args ...string) (int, string, error) {args = append([]string{"-c"}, args...)cmd := exec.Command(os.Getenv("SHELL"), args...) cmd.SysProcAttr = &syscall.SysProcAttr{} outpip, err := cmd.StdoutPipe()
defer outpip.Close()
if err != nil {return 0,"", err} err = cmd.Start()if err != nil {return 0,"", err} out, err := ioutil.ReadAll(outpip)if err != nil {return 0,"", err} return cmd.Process.Pid, string(out), nil} // 异步执行命令行并通过channel返回结果// stdout: chan结果// args: 命令行参数// return: 进程的pid// exception: 协程内的命令行发生错误时,会panic异常func (lc *LinuxCommand) ExecAsync(stdoutchan string, args ...string) int {var pidChan = make(chan int, 1) go func() {args = append([]string{"-c"}, args...)cmd := exec.Command(os.Getenv("SHELL"), args...) cmd.SysProcAttr = &syscall.SysProcAttr{} outpip, err := cmd.StdoutPipe()
defer outpip.Close()
if err != nil {panic(err)} err = cmd.Start()if err != nil {panic(err)} pidChan

Exec函数会在执行命令行后阻塞,直到得到命令的执行结果;ExecAsync函数在内部使用了协程来执行命令行,并通过参数中的chan变量把结果传递出去;ExecNoWait会无阻赛地执行命令行.Windows平台上的实现类似,只是Shell命令换成了cmd.

使用示例如下:package main import ("log" "github.com/lizongshen/gocommand") func main() {_, out, err := gocommand.NewCommand().Exec("ls /")if err != nil {log.Panic(err)} log.Println(out) }

代码的单元测试情况:[lizongshen@localhost gocommand]$ gotestbin   dev  home  lib64  mnt  proc  run   srv  tmp  varboot  etc  lib   media  opt  root  sbin  sys  usrPASSok      gocommand   0.007s

作者:Lizongshen

出处:http://www.cnblogs.com/lizongshen/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值