美文网首页
golang 批量scp 远程传输文件

golang 批量scp 远程传输文件

作者: 凡城长路 | 来源:发表于2017-10-31 11:40 被阅读0次

最近公司遇到一个问题,需要拷贝大量图片到远程机器上去。
直接上代码,

// main.go
package main

import (
    "fmt"
    "log"
    "net"
    "os"
    "path"
    "time"

    "github.com/pkg/sftp"
    "golang.org/x/crypto/ssh"
)
func sshconnect(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
}

func sftpconnect(user, password, host string, port int) (*sftp.Client, error) {
    var (
        auth         []ssh.AuthMethod
        addr         string
        clientConfig *ssh.ClientConfig
        sshClient    *ssh.Client
        sftpClient   *sftp.Client
        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,
              //这个是问你要不要验证远程主机,以保证安全性。这里不验证
        HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
            return nil
        },
    }

    // connet to ssh
    addr = fmt.Sprintf("%s:%d", host, port)

    if sshClient, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
        return nil, err
    }

    // create sftp client
    if sftpClient, err = sftp.NewClient(sshClient); err != nil {
        return nil, err
    }

    return sftpClient, nil
}


//单个copy
func scpCopy(localFilePath, remoteDir string) error {
    var (
        sftpClient *sftp.Client
        err        error
    )
    // 这里换成实际的 SSH 连接的 用户名,密码,主机名或IP,SSH端口
    sftpClient, err = sftpconnect("user", "passwd", "目的机器的ip", 目的机器的端口)
    if err != nil {
        log.Println("scpCopy:", err)
        return err
    }
    defer sftpClient.Close()
    srcFile, err := os.Open(localFilePath)
    if err != nil {
        log.Println("scpCopy:", err)
        return err
    }
    defer srcFile.Close()

    var remoteFileName = path.Base(localFilePath)
    dstFile, err := sftpClient.Create(path.Join(remoteDir, remoteFileName))
    if err != nil {
        log.Println("scpCopy:", err)
        return err
    }
    defer dstFile.Close()

    buf := make([]byte, 1024)
    for {
        n, _ := srcFile.Read(buf)
        if n == 0 {
            break
        }
        dstFile.Write(buf[0:n])
    }
    return nil
}

这里是批量copy

//批量copy
func scpListCopy(cinfos []CouponInfo) error {
    var localFilePath, remoteDir string

    // 这里换成实际的 SSH 连接的 用户名,密码,主机名或IP,SSH端口
    sshftpClient := NewSftpClient()

    // 用来测试的本地文件路径 和 远程机器上的文件夹
    for _, v := range cinfos {
        for i := 0; i < len(v.Coupons); i++ {
            localFilePath = v.Coupons[i].Addr
            remoteDir = "目的地址"

            srcFile, err := os.Open(localFilePath)
            if err != nil {
                logger.Println("scpListCopy1:", err)
                return err
            }
            defer srcFile.Close()

            var remoteFileName = path.Base(localFilePath)
            dstFile, err := sshftpClient.Create(path.Join(remoteDir, remoteFileName))
            if err != nil {
                logger.Println("scpListCopy2:", err)
                return err
            }
            defer dstFile.Close()

            buf := make([]byte, 1024)
            for {
                n, _ := srcFile.Read(buf)
                if n == 0 {
                    break
                }
                dstFile.Write(buf[0:n])
            }
        }
    }
    return nil
}
/*
NewSftpClient 这个方法,此文件应该有个全局变量
var sftpClient *sftp.Client
全局变量,保证不会出现tcp关闭不掉的错误,这个恶心的错误就是:
 ssh: unexpected packet in response to channel open: <nil>
*/
func NewSftpClient() *sftp.Client {
    var err error
    if sftpClient == nil {
        sftpClient, err = sftpconnect("duyq", "duyuqing123456", "10.250.129.22", 22)
        if err != nil {
            logger.Fatalln("NewSftpClient:", err)
        }
    }
    return sftpClient
}

相关文章

  • golang 批量scp 远程传输文件

    最近公司遇到一个问题,需要拷贝大量图片到远程机器上去。直接上代码, 这里是批量copy

  • scp 和 screen

    scp命令可以实现在linux系统之间安全的传输文件 scp [参数] 本地文件 远程主机账户@远程主机地址:远程...

  • SCP远程拷贝文件

    Linux 远程传输文件及目录 SCP 复制文件或目录命令: 复制文件: (1)将本地文件拷贝到远程scp 文件名...

  • Linux实用命令合辑

    在Linux设备之间传输文件 scp scp 本地文件路径 原生用户名@主机:远程路径 示例: scp ~/do...

  • Linux常用命令

    scp命令 scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令, scp传输是加密的,...

  • 解决scp连接远程传输报错The authenticity of

    linux下使用scp远程传输文件时,提示如下: The authenticity of host 'hserve...

  • SCP服务传输文件

    简介 scp是用于远程拷贝文件,类似于本地拷贝文件命令cp,scp传输是加密传输,并且不占用系统资源。可能会稍微影...

  • Python的scp小工具

    scp简单实现 scp是我们在shell上经常使用的命令,用来远程传输文件。python上也能做到scp的功能,需...

  • scp命令使用总结

    简介 scp是secure copy的缩写,Linux下进行远程拷贝文件的命令。scp传输是加密的。 命令格式 使...

  • windows scp使用

    先进入要传输文件的目录 scp 文件名 远程主机用户名@liyafeng,com:/文件夹名

网友评论

      本文标题:golang 批量scp 远程传输文件

      本文链接:https://www.haomeiwen.com/subject/bffbpxtx.html