Go语言cmd命令通过管道实现交互

幸运草
幸运草
幸运草
896
文章
3
评论
2020年4月18日19:52:51 评论 103

由于对于技术的追新欲望,让我想要把现有的一些逻辑在新技术上尝试。因此拿了一个在python上实现好的功能,翻到go中进行实现。在Python实现这种交互很简单使用popen2就可以简单实现。但是Go语言如何实现呢?接下来我就给大家实现此功能

 

为什么需要这种交互

在公司里开发涉及到围棋领域AI的对接,一种通用的方式就是通过Go Text Protocol协议与不同AI进行对接,下文将以对接一种AI(gungo)进行样例说明。现在让我们进入正题吧……

 

 

 

接下来将使用exec.Cmd进行以上功能实现。首先通读一次exec.Cmd的文档实现各种各个方法的实现。从中找到cmd.StdinPipe,cmd.StdoutPipe基本可以定位实现的方式了。话不多说下面上代码……

// GTP_Connection GTP连接类管理

type GTPConnection struct {

    cmd *exec.Cmd

    infile io.WriteCloser

    outfile io.ReadCloser

}

首先定义一个实现类,用于后续交互其中有三个属性分别是cmd用于命令对象保存,infile为输入管道,outfile为输出管道。

// NewConnection 创建GTP连接

func NewConnection(cmd string, args ...string) (*GTPConnection, error) {

    conn := GTPConnection{}

    conn.cmd = exec.Command(cmd, args...)

    inf, err := conn.cmd.StdinPipe()

    if err != nil {

        return &conn, err

    }

    outf, err := conn.cmd.StdoutPipe()

    if err != nil {

        return &conn, err

    }

    conn.infile = inf

    conn.outfile = outf

    conn.cmd.Start()

    go func() {

        conn.cmd.Wait()

    }()

    return &conn, nil

}

创建命令,并得到输入输出管道,cmd.Start()开始命令,cmd.Wait()等待命令结束,需要使用go异步化,不然会阻塞程序执行。

// Exec 执行GTP命令

func (self GTPConnection) Exec(cmd string) (string, error) {

    self.infile.Write([]byte(fmt.Sprintf("%s n", cmd)))

    reader := bufio.NewReader(self.outfile)

    result := ""

    for {

        line, err2 := reader.ReadString('n')

        if err2 != nil || io.EOF == err2 {

            break

        }

        if line == "n" {

            break

        }

        result += line

    }

    res := strings.Split(result, "")

    l := len(res)

    if res[l-1] == "n" {

        result = strings.Join(res[:l-1], "")

    }

    if len(result) == 0 {

        return "", errors.New("len =0")

    }

    if res[0] == "?" {

        return "", errors.New(fmt.Sprintf("ERROR: GTP Command failed:%s", strings.Join(res[2:], "")))

    }

    if res[0] == "=" {

        return strings.Join(res[2:], ""), nil

    }

    return "", errors.New(fmt.Sprintf("ERROR: Unrecognized answer: %s", result))

}

执行方法,首先通过输入管道执行命令,再通过输出管道得到响应结果
 

 

特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

转载请注明:{{title}}-变化吧
  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 赞助本站
  • 支付宝扫一扫
  • weinxin
幸运草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" )...