iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >golang如何调用shell命令
  • 253
分享到

golang如何调用shell命令

2023-07-05 04:07:55 253人浏览 八月长安
摘要

这篇文章主要介绍了golang如何调用shell命令的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang如何调用shell命令文章都会有所收获,下面我们一起来看看吧。普通用法(一次性获取所有输出)pack

这篇文章主要介绍了golang如何调用shell命令的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang如何调用shell命令文章都会有所收获,下面我们一起来看看吧。

    普通用法(一次性获取所有输出)

    package mainimport (    "fmt"    "os/exec")func main() {    Command("ls")}// 这里为了简化,我省去了stderr和其他信息func Command(cmd string) error {    c := exec.Command("bash", "-c", cmd)    // 此处是windows版本    // c := exec.Command("cmd", "/C", cmd)    output, err := c.CombinedOutput()    fmt.Println(string(output))    return err}

    可以看到,当前命令执行的是输出当前目录下的文件/文件夹

    golang如何调用shell命令

    实时显示

    效果图:

    golang如何调用shell命令

    package mainimport (    "bufio"    "fmt"    "io"    "os/exec"    "sync")func main() {    // 执行ping baidu的命令, 命令不会结束    Command("ping www.baidu.com")}func Command(cmd string) error {    //c := exec.Command("cmd", "/C", cmd)   // windows    c := exec.Command("bash", "-c", cmd)  // Mac or linux    stdout, err := c.StdoutPipe()    if err != nil {        return err    }    var wg sync.WaitGroup    wg.Add(1)    go func() {        defer wg.Done()        reader := bufio.NewReader(stdout)        for {            readString, err := reader.ReadString('\n')            if err != nil || err == io.EOF {                return            }            fmt.Print(readString)        }    }()    err = c.Start()    wg.Wait()    return err}

    可关闭+实时输出

    package mainimport (    "bufio"    "context"    "fmt"    "io"    "os/exec"    "sync"    "time")func main() {    ctx, cancel := context.WithCancel(context.Background())    go func(cancelFunc context.CancelFunc) {        time.Sleep(3 * time.Second)        cancelFunc()    }(cancel)    Command(ctx, "ping www.baidu.com")}func Command(ctx context.Context, cmd string) error {    // c := exec.CommandContext(ctx, "cmd", "/C", cmd)    c := exec.CommandContext(ctx, "bash", "-c", cmd) // mac linux    stdout, err := c.StdoutPipe()    if err != nil {        return err    }    var wg sync.WaitGroup    wg.Add(1)    go func(wg *sync.WaitGroup) {        defer wg.Done()        reader := bufio.NewReader(stdout)        for {            // 其实这段去掉程序也会正常运行,只是我们就不知道到底什么时候Command被停止了,而且如果我们需要实时给WEB端展示输出的话,这里可以作为依据 取消展示            select {            // 检测到ctx.Done()之后停止读取            case <-ctx.Done():                if ctx.Err() != nil {                    fmt.Printf("程序出现错误: %q", ctx.Err())                } else {                    fmt.Println("程序被终止")                }                return            default:                readString, err := reader.ReadString('\n')                if err != nil || err == io.EOF {                    return                }                fmt.Print(readString)            }        }    }(&wg)    err = c.Start()    wg.Wait()    return err}

    效果图:

    golang如何调用shell命令

    可以看到输出了3次(1秒1次)之后程序就被终止了,确切的说是读取输出流的循环结束了。

    执行python脚本(阻塞)

    其实很简单,只要Python -u xxx.py这样执行就可以了, -u参数

    简单的说就是python的输出是有缓存的,-u会强制往标准流输出,当Python脚本阻塞的时候

    也不会拿不到输出!

    其他

    "bash" 和"-c",据我的观察,这2个参数代表在当前cmd窗口执行,而不加这2个参数,直接上shell的话,会启动一个新窗口,目前观察是stdout拿不到数据。

    仍有缺陷

    上面的命令可以解决大部分问题,但是获取不到stderr的信息,所以我们需要改造一下。

    下面是输出和错误一并输出的实时读取,类似于jenkins那种。

    package mainimport (    "bufio"    "context"    "fmt"    "io"    "os/exec"    "sync"    "time")func main() {    ctx, cancel := context.WithCancel(context.Background())    go func(cancelFunc context.CancelFunc) {        time.Sleep(3 * time.Second)        cancelFunc()    }(cancel)    Command(ctx, "ping www.baidu.com")}func read(ctx context.Context, wg *sync.WaitGroup, std io.ReadCloser) {    reader := bufio.NewReader(std)    defer wg.Done()    for {        select {        case <-ctx.Done():            return        default:            readString, err := reader.ReadString('\n')            if err != nil || err == io.EOF {                return            }            fmt.Print(readString)        }    }}func Command(ctx context.Context, cmd string) error {    //c := exec.CommandContext(ctx, "cmd", "/C", cmd) // windows    c := exec.CommandContext(ctx, "bash", "-c", cmd) // mac linux    stdout, err := c.StdoutPipe()    if err != nil {        return err    }    stderr, err := c.StderrPipe()    if err != nil {        return err    }    var wg sync.WaitGroup    // 因为有2个任务, 一个需要读取stderr 另一个需要读取stdout    wg.Add(2)    go read(ctx, &wg, stderr)    go read(ctx, &wg, stdout)    // 这里一定要用start,而不是run 详情请看下面的图    err = c.Start()    // 等待任务结束    wg.Wait()    return err}

    golang如何调用shell命令

    windows输出乱码问题

    最后给一个解决windows乱码的完整案例

    package mainimport (    "bufio"    "fmt"    "io"    "os/exec"    "sync"    "golang.org/x/text/encoding/simplifiedchinese")type Charset strinGConst (    UTF8    = Charset("UTF-8")    GB18030 = Charset("GB18030"))func main() {    // 执行ping baidu的命令, 命令不会结束    Command("ping www.baidu.com")}func Command(cmd string) error {    //c := exec.Command("cmd", "/C", cmd)   // windows    c := exec.Command("bash", "-c", cmd)  // mac or linux    stdout, err := c.StdoutPipe()    if err != nil {        return err    }    var wg sync.WaitGroup    wg.Add(1)    go func() {        defer wg.Done()        reader := bufio.NewReader(stdout)        for {            readString, err := reader.ReadString('\n')            if err != nil || err == io.EOF {                return            }            byte2String := ConvertByte2String([]byte(readString), "GB18030")            fmt.Print(byte2String)        }    }()    err = c.Start()    wg.Wait()    return err}func ConvertByte2String(byte []byte, charset Charset) string {    var str string    switch charset {    case GB18030:        var decodeBytes, _ = simplifiedchinese.GB18030.NewDecoder().Bytes(byte)        str = string(decodeBytes)    case UTF8:        fallthrough    default:        str = string(byte)    }    return str}

    概述

    远程执行命令有什么用?为什么要远程执行命令? 如果你只有2,3台服务器需要管理的时候,远程执行命令确实没有没多大作用,你可以登录到每台服务器上去完成各种操作。 当你的服务器大于3台的时候,远程执行的命令的方式就可以大大提高你的生产力了。

    如果你有一个可以远程执行命令的工具,那么就可以像操作单台机器那样操作多台机器,机器越多,效率提高的越多。 远程执行命令最常用的方法就是利用 ssh 协议,将命令发送到远程机器上执行,并获取返回结果。

    本文介绍如何使用 golang 实现远程执行命令。

    一般命令

    所谓一般命令,就是在一定时间内会执行完的命令。比如 grep, cat 等等。 执行命令的步骤是:连接,执行,获取结果

    连接

    连接包含了认证,可以使用 passWord 或者 sshkey 2种方式来认证。下面的示例为了简单,使用了密码认证的方式来完成连接。

    import (    "fmt"  "time"  "golang.org/x/crypto/ssh")func connect(user, password, host string, port int) (*ssh.Session, error) {    var (    auth         []ssh.AuthMethod    addr         string    clientConfig *ssh.ClientConfig    client       *ssh.Client    session      *ssh.Session    err          error  )  // get auth method  auth = make([]ssh.AuthMethod, 0)  auth = append(auth, ssh.Password(password))  clientConfig = &ssh.ClientConfig{    User:    user,    Auth:    auth,    Timeout: 30 * time.Second,  }  // connet to ssh  addr = fmt.Sprintf("%s:%d", host, port)  if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {    return nil, err  }  // create session  if session, err = client.NewSession(); err != nil {    return nil, err  }  return session, nil}

    连接的方法很简单,只要提供登录主机的 用户*, *密码*, *主机名或者IP*, *SSH端口

    执行,命令获取结果

    连接成功后,执行命令很简单

    import (    "fmt"  "log"  "os"  "time"  "golang.org/x/crypto/ssh")func main() {    session, err := connect("root", "xxxxx", "127.0.0.1", 22)  if err != nil {    log.Fatal(err)  }  defer session.Close()  session.Run("ls /; ls /abc")}

    上面代码运行之后,虽然命令正常执行了,但是没有正常输出的结果,也没有异常输出的结果。 要想显示结果,需要将 session 的 Stdout 和 Stderr 重定向 修改 func main 为如下:

    func main() {    session, err := connect("root", "xxxxx", "127.0.0.1", 22)  if err != nil {    log.Fatal(err)  }  defer session.Close()  session.Stdout = os.Stdout  session.Stderr = os.Stderr  session.Run("ls /; ls /abc")}

    这样就能在屏幕上显示正常,异常的信息了。

    交互式命令

    上面的方式无法远程执行交互式命令,比如 top , 远程编辑一个文件,比如 vi /etc/nginx/nginx.conf 如果要支持交互式的命令,需要当前的terminal来接管远程的 PTY。

    func main() {    session, err := connect("root", "olordjesus", "Dockers.iotalabs.io", 2210)  if err != nil {    log.Fatal(err)  }  defer session.Close()  fd := int(os.Stdin.Fd())  oldState, err := terminal.MakeRaw(fd)  if err != nil {    panic(err)  }  defer terminal.Restore(fd, oldState)  // excute command  session.Stdout = os.Stdout  session.Stderr = os.Stderr  session.Stdin = os.Stdin  termWidth, termHeight, err := terminal.GetSize(fd)  if err != nil {    panic(err)  }  // Set up terminal modes  modes := ssh.TerminalModes{    ssh.ECHO:          1,     // enable echoing    ssh.TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud    ssh.TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud  }  // Request pseudo terminal  if err := session.RequestPty("xterm-256color", termHeight, termWidth, modes); err != nil {    log.Fatal(err)  }  session.Run("top")}

    这样就可以执行交互式命令了,比如上面的 top 也可以通过 vi /etc/nginx/nignx.conf 之类的命令来远程编辑文件。

    关于“golang如何调用shell命令”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“golang如何调用shell命令”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网GO频道。

    您可能感兴趣的文档:

    --结束END--

    本文标题: golang如何调用shell命令

    本文链接: https://www.lsjlt.com/news/349560.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • golang如何调用shell命令
      这篇文章主要介绍了golang如何调用shell命令的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇golang如何调用shell命令文章都会有所收获,下面我们一起来看看吧。普通用法(一次性获取所有输出)pack...
      99+
      2023-07-05
    • golang调用shell命令(实时输出,终止)
      目录背景普通用法(一次性获取所有输出)实时显示可关闭+实时输出执行Python脚本(阻塞)其他仍有缺陷windows输出乱码问题最后给一个解决windows乱码的完整案例概述一般命令...
      99+
      2023-02-21
      golang调用shell命令 golang调用shell
    • golang调用shell命令失败怎么解决
      如果在Golang中调用shell命令失败,可以尝试以下几种解决办法: 检查命令是否正确:确保调用的shell命令是正确的,可以...
      99+
      2023-10-26
      golang shell
    • perl怎么调用shell命令
      在Perl中,可以使用反引号或`qx//`操作符来调用shell命令。使用反引号调用shell命令的示例:```perlmy $ou...
      99+
      2023-10-07
      perl
    • python调用shell命令小结
       在写python脚本的时候,经常需要调用系统命令,常用的python调用系统命令的方法主要有subprocess.call和os.popen。默认情况下subprocess.call的方法结果是返回值,即1或0,而os.popen则是命令...
      99+
      2023-01-31
      小结 命令 python
    • python怎么调用shell命令
      在Python中,可以使用`subprocess`模块来调用shell命令。下面是一个简单的示例:```pythonimport s...
      99+
      2023-08-30
      python shell
    • java怎么调用shell命令
      Java中可以通过`Runtime`类或者`ProcessBuilder`类来调用shell命令。1. 使用`Runtime`类调用...
      99+
      2023-09-29
      java
    • shell如何使用date命令
      小编给大家分享一下shell如何使用date命令,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!date$ date&n...
      99+
      2024-04-02
    • Golang怎么应用执行Shell命令
      今天小编给大家分享一下Golang怎么应用执行Shell命令的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。exec包使用官方...
      99+
      2023-07-05
    • Golang应用执行Shell命令实战
      目录exec包运行基本Shell命令执行长时间运行命令自定义写输出使用Stdin给命令传递输入结束子进程总结本文学习如何在Golang程序中执行Shell命令(如,ls,mkdir或...
      99+
      2023-03-19
      Golang执行Shell命令 Golang执行Shell
    • golang代码中调用Linux命令
      目录传统方案--crontab分布式任务调度go执行shell命令实际我们在golang代码中调用linux命令1、普通调用2、结合协程调用,可控制中断调用传统方案--crontab 缺点配置任务时,需要SSh登录脚本服...
      99+
      2023-02-19
      golang调用Linux命令 golangLinux命令
    • Shell中select命令如何使用
      Shell中select命令如何使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。select格式如下:  select $var...
      99+
      2023-06-09
    • Shell中如何使用test命令
      这篇文章将为大家详细讲解有关Shell中如何使用test命令,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方...
      99+
      2023-06-05
    • Shell之declare命令如何使用
      在Shell中,declare命令用于声明变量的属性和类型。declare命令的语法如下:```declare [选项] 变量名[=...
      99+
      2023-09-29
      Shell
    • Java怎么调用Shell命令和脚本
      这篇文章主要为大家展示了Java怎么调用Shell命令和脚本,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“Java怎么调用Shell命令和脚本”这篇文章吧。Java可以用来干什么Java主要应用于...
      99+
      2023-06-06
    • 怎么使用golang执行Linux shell命令
      这篇文章主要讲解了“怎么使用golang执行Linux shell命令”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用golang执行Linux shell命令”吧...
      99+
      2023-07-02
    • 如何在shell中使用source命令
      这篇文章将为大家详细讲解有关如何在shell中使用source命令,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 sh filepath会重新建立一个子shell,在子shell中执行脚本里...
      99+
      2023-06-09
    • 如何在 NumPy 中使用 Shell 命令?
      NumPy 是 Python 中一个重要的科学计算库,它提供了高效的数组操作、线性代数运算、傅里叶变换等基础数学函数。与此同时,Python 也是一个强大的脚本语言,能够方便地执行各种系统命令。因此,本文将介绍如何在 NumPy 中使用 S...
      99+
      2023-08-27
      numy path shell
    • 如何使用Shell脚本test命令
      这篇文章主要讲解了“如何使用Shell脚本test命令”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何使用Shell脚本test命令”吧!Shell中的 test 命令用于检查某个条件是否...
      99+
      2023-06-09
    • 如何用PHP执行shell 脚本和 shell命令
      执行 shell 脚本: 或者首先使用 ssh2_connect 函数连接到远程主机,然后使用 ssh2_auth_password 函数进行身份验证。接下来,使用 ssh2_exec 函数执行 shell 脚本,将其输出流作为结果返回。...
      99+
      2023-08-31
      php linux 开发语言 Powered by 金山文档
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作