为了账号安全,请及时绑定邮箱和手机立即绑定

在 go 中通过 SSH 发送文件

在 go 中通过 SSH 发送文件

Go
万千封印 2023-05-08 15:47:50
我在发布这个问题之前找到了这个答案,但我不清楚答案。这是答案的代码:conn, err := ssh.Dial("tcp", hostname+":22", config)if err != nil {    return err}session, err := conn.NewSession()if err != nil {    return err}defer session.Close()r, err := session.StdoutPipe()if err != nil {    return err}name := fmt.Sprintf("%s/backup_folder_%v.tar.gz", path, time.Now().Unix())file, err := os.OpenFile(name, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)if err != nil {    return err}defer file.Close()if err := session.Start(cmd); err != nil {    return err}n, err := io.Copy(file, r)if err != nil {    return err}if err := session.Wait(); err != nil {    return err}return nil我不明白 cmd 变量和 io.Copy 之间的关系,它在哪里以及如何知道要复制哪个文件。我喜欢使用 io.Copy 的想法,但我不知道如何通过 ssh 创建文件并开始使用 io.Copy 向它发送内容。
查看完整描述

2 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

您也可以使用 sftp 包 - “github.com/pkg/sftp”



func SSHCopyFile(srcPath, dstPath string) error {

    config := &ssh.ClientConfig{

        User: "user",

        Auth: []ssh.AuthMethod{

            ssh.Password("pass"),

        },

        HostKeyCallback: ssh.InsecureIgnoreHostKey(),

    }


    client, _ := ssh.Dial("tcp", "remotehost:22", config)

    defer client.Close()



    // open an SFTP session over an existing ssh connection.

    sftp, err := sftp.NewClient(client)

    if err != nil {

        return err

    }

    defer sftp.Close()


    // Open the source file

    srcFile, err := os.Open(srcPath)

    if err != nil {

        return err

    }

    defer srcFile.Close()


    // Create the destination file

    dstFile, err := sftp.Create(dstPath)

    if err != nil {

        return err

    }

    defer dstFile.Close()


    // write to file

    if  _, err := dstFile.ReadFrom(srcFile); err!= nil {

        return err

    }

    return nil

}


然后像这样称呼它


SSHCopyFile("/path/to/local/file.txt", "/path/on/remote/file.txt")

这些是必需的包


"github.com/pkg/sftp"

"golang.org/x/crypto/ssh"


查看完整回答
反对 回复 2023-05-08
?
不负相思意

TA贡献1777条经验 获得超10个赞

这是一个关于如何将 Go 作为scp客户端使用的最小示例:


config := &ssh.ClientConfig{

    User: "user",

    Auth: []ssh.AuthMethod{

        ssh.Password("pass"),

    },

    HostKeyCallback: ssh.InsecureIgnoreHostKey(),

}


client, _ := ssh.Dial("tcp", "remotehost:22", config)

defer client.Close()


session, _ := client.NewSession()

defer session.Close()


file, _ := os.Open("filetocopy")

defer file.Close()

stat, _ := file.Stat()


wg := sync.WaitGroup{}

wg.Add(1)


go func() {

    hostIn, _ := session.StdinPipe()

    defer hostIn.Close()

    fmt.Fprintf(hostIn, "C0664 %d %s\n", stat.Size(), "filecopyname")

    io.Copy(hostIn, file)

    fmt.Fprint(hostIn, "\x00")

    wg.Done()

}()


session.Run("/usr/bin/scp -t /remotedirectory/")

wg.Wait()

请注意,为了简洁起见,我忽略了所有错误。

  1. session.StdinPipe()将为远程主机创建一个可写管道。

  2. fmt.Fprintf(... "C0664 ...")0664将用权限、stat.Size()大小和远程文件名来表示文件的开始filecopyname

  3. io.Copy(hostIn, file)将 的内容file写入hostIn.

  4. fmt.Fprint(hostIn, "\x00")将发出文件结束信号。

  5. session.Run("/usr/bin/scp -qt /remotedirectory/")将运行 scp 命令。

编辑:根据 OP 的请求添加等待组


查看完整回答
反对 回复 2023-05-08
  • 2 回答
  • 0 关注
  • 175 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信