golang使用sftp连接服务器远程上传、下载文件

安装github.com/pkg/sftp

我们之前介绍了,golang如何通过ssh连接服务器执行命令,下面我们来如何上传文件,上传文件同样需要之前的ssh,但是除此之外还需要一个模块,直接使用go get github.com/pkg/sftp安装即可

使用

package main

import (
    "fmt"
    "github.com/pkg/sftp"
    "golang.org/x/crypto/ssh"
    "io"
    "log"
    "net"
    "os"
    "time"
)

//连接的配置
type ClientConfig struct {
    Host       string       //ip
    Port       int64        // 端口
    Username   string       //用户名
    Password   string       //密码
    sshClient  *ssh.Client  //ssh client
    sftpClient *sftp.Client //sftp client
    LastResult string       //最近一次运行的结果
}

func (cliConf *ClientConfig) createClient(host string, port int64, username, password string) {
    var (
        sshClient  *ssh.Client
        sftpClient *sftp.Client
        err        error
    )
    cliConf.Host = host
    cliConf.Port = port
    cliConf.Username = username
    cliConf.Password = password
    cliConf.Port = port

    config := ssh.ClientConfig{
        User: cliConf.Username,
        Auth: []ssh.AuthMethod{ssh.Password(password)},
        HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
            return nil
        },
        Timeout: 10 * time.Second,
    }
    addr := fmt.Sprintf("%s:%d", cliConf.Host, cliConf.Port)

    if sshClient, err = ssh.Dial("tcp", addr, &config); err != nil {
        log.Fatalln("error occurred:", err)
    }
    cliConf.sshClient = sshClient

    //此时获取了sshClient,下面使用sshClient构建sftpClient
    if sftpClient, err = sftp.NewClient(sshClient); err != nil {
        log.Fatalln("error occurred:", err)
    }
    cliConf.sftpClient = sftpClient
}

func (cliConf *ClientConfig) RunShell(shell string) string {
    var (
        session *ssh.Session
        err     error
    )

    //获取session,这个session是用来远程执行操作的
    if session, err = cliConf.sshClient.NewSession(); err != nil {
        log.Fatalln("error occurred:", err)
    }
    //执行shell
    if output, err := session.CombinedOutput(shell); err != nil {
        fmt.Println(shell)
        log.Fatalln("error occurred:", err)
    } else {
        cliConf.LastResult = string(output)
    }
    return cliConf.LastResult
}

func (cliConf *ClientConfig) Upload(srcPath, dstPath string){
    srcFile, _ := os.Open(srcPath) //本地
    dstFile, _ := cliConf.sftpClient.Create(dstPath) //远程
    defer func() {
        _ = srcFile.Close()
        _ = dstFile.Close()
    }()
    buf := make([]byte, 1024)
    for {
        n, err := srcFile.Read(buf)
        if err != nil {
            if err != io.EOF {
                log.Fatalln("error occurred:",err)
            } else {
                break
            }
        }
        _, _ = dstFile.Write(buf[: n])
    }
    fmt.Println(cliConf.RunShell(fmt.Sprintf("ls %s", dstPath)))
}

func (cliConf *ClientConfig) Download(srcPath, dstPath string){
    srcFile, _ := cliConf.sftpClient.Open(srcPath) //远程
    dstFile, _ := os.Create(dstPath) //本地
    defer func() {
        _ = srcFile.Close()
        _ = dstFile.Close()
    }()

    if _, err := srcFile.WriteTo(dstFile); err != nil {
        log.Fatalln("error occurred", err)
    }
    fmt.Println("文件下载完毕")
}

func main() {
    cliConf := new(ClientConfig)
    cliConf.createClient("xx.xx.xx.xx", 22, "root", "xxxxxx")
    //本地文件上传到服务器
    cliConf.Upload(`D:\go\haha.go`, `/root/haha.go`) // /root/haha.go
    //从服务器中下载文件
    cliConf.Download(`/root/1.py`, `D:\go\1.py`) //文件下载完毕
}

猜你喜欢

转载自www.cnblogs.com/traditional/p/11894550.html