首页 技术 正文
技术 2022年11月6日
0 收藏 657 点赞 926 浏览 2213 个字

使用包:golang.org/x/crypto/ssh

以下封装一个发送命令的Cli结构体

package utilsimport (
"fmt"
"golang.org/x/crypto/ssh"
"golang.org/x/crypto/ssh/terminal"
"io"
"net"
"os"
"time"
)type Cli struct {
IP string //IP地址
Username string //用户名
Password string //密码
Port int //端口号
client *ssh.Client //ssh客户端
LastResult string //最近一次Run的结果
}//创建命令行对象
//@param ip IP地址
//@param username 用户名
//@param password 密码
//@param port 端口号,默认22
func New(ip string, username string, password string, port ...int) *Cli {
cli := new(Cli)
cli.IP = ip
cli.Username = username
cli.Password = password
if len(port) <= 0 {
cli.Port = 22
} else {
cli.Port = port[0]
}
return cli
}//执行shell
//@param shell shell脚本命令
func (c Cli) Run(shell string) (string, error) {
if c.client == nil {
if err := c.connect(); err != nil {
return "", err
}
}
session, err := c.client.NewSession()
if err != nil {
return "", err
}
defer session.Close()
buf, err := session.CombinedOutput(shell)c.LastResult = string(buf)
return c.LastResult, err
}
//连接
func (c *Cli) connect() error {
config := ssh.ClientConfig{
User: c.Username,
Auth: []ssh.AuthMethod{ssh.Password(c.Password)},
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
Timeout: 10 * time.Second,
}
addr := fmt.Sprintf("%s:%d", c.IP, c.Port)
sshClient, err := ssh.Dial("tcp", addr, &config)
if err != nil {
return err
}
c.client = sshClient
return nil
}

测试执行shell代码

    cli := New("IP", "用户名", "密码", 端口号)
output, err := cli.Run("free -h")
fmt.Printf("%v\n%v", output, err)

还有类似top或者vim的命令是需要交互的,可以利用包golang.org/x/crypto/ssh/terminal实现

再封装一个方法RunTerminal

//执行带交互的命令
func (c *Cli) RunTerminal(shell string, stdout, stderr io.Writer) error {
if c.client == nil {
if err := c.connect(); err != nil {
return err
}
}
session, err := c.client.NewSession()
if err != nil {
return err
}
defer session.Close() fd := int(os.Stdin.Fd())
oldState, err := terminal.MakeRaw(fd)
if err != nil {
panic(err)
}
defer terminal.Restore(fd, oldState) session.Stdout = stdout
session.Stderr = 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 {
return err
} session.Run(shell)
return nil
}

测试RunTerminal方法

    cli := New("IP", "用户名", "密码", 端口号)
    cli.RunTerminal("top", os.Stdout, os.Stdin)
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,958
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,482
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,328
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,111
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,743
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,777