如何使用Go语言实现远程执行命令

作者:daisy 时间:2024-04-25 15:16:39 

前言

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

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

一般命令

所谓一般命令,就是在一定时间内会执行完的命令。比如 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 之类的命令来远程编辑文件。以上就是如何使用Go语言实现远程执行命令的全部内容了,希望本文对大家学习python有所帮助。

标签:golang,执行命令,远程
0
投稿

猜你喜欢

  • ASP连接Access数据库的几种方法

    2013-06-01 20:33:19
  • python 三种方法提取pdf中的图片

    2023-09-18 08:25:58
  • DenseNet121模型实现26个英文字母识别任务

    2023-08-22 13:15:22
  • Python异常处理操作实例详解

    2023-05-06 11:31:05
  • 用mysql做站点时怎样记录未知错误的发生

    2009-01-14 13:16:00
  • python并发编程之多进程、多线程、异步和协程详解

    2021-12-10 00:20:35
  • ExtJS判断IE浏览器类型的方法

    2024-05-13 10:35:56
  • Python中在for循环中嵌套使用if和else语句的技巧

    2022-10-08 17:44:50
  • Golang语言如何避免空指针引发的panic详解

    2024-05-29 22:07:59
  • JSP页面传参出现中文乱码的解决方案

    2023-06-13 12:53:03
  • golang 比较浮点数的大小方式

    2024-04-28 10:48:50
  • vue.js前端网页弹框异步行为示例分析

    2024-04-28 09:21:58
  • Python中Playwright 与 pyunit 结合使用详解

    2022-04-30 10:42:42
  • Django的ListView超详细用法(含分页paginate)

    2021-02-13 00:53:41
  • python协程之yield和yield from实例详解

    2022-10-31 05:47:42
  • 如何配置关联Python 解释器 Anaconda的教程(图解)

    2021-06-13 15:27:30
  • Python from import导包ModuleNotFoundError No module named找不到模块问题解决

    2023-07-27 20:06:53
  • ORACLE 报警日志如何查看?第1/2页

    2009-07-02 12:06:00
  • Mysql索引性能优化问题解决方案

    2024-01-27 12:14:41
  • win10下python2和python3共存问题解决方法

    2022-11-05 09:08:38
  • asp之家 网络编程 m.aspxhome.com