drfqfuhej48511519
2018-11-12 05:29
浏览 148
已采纳

在Go中通过SSH发送文件

I found this answer before posting this question but the answer is not clear to me.

Here is the code of the answer:

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

I don't understand relation between the cmd variable and io.Copy, where and how does it know which file to copy. I like the idea of using io.Copy but i do not know how to create the file via ssh and start sending content to it using io.Copy.

图片转代码服务由CSDN问答提供 功能建议

我在发布此问题之前找到了这个答案,但是答案对我来说并不明确。

以下是答案的代码:

  conn,错误:= ssh.Dial(“ tcp”,主机名+“:22”,配置)
if错误!= nil {
 return err 
} 
 
session,  err:= conn.NewSession()
if err!= nil {
返回err 
} 
defer session.Close()
 
r,err:= session.StdoutPipe()
if err!= nil {\  n return err 
} 
 
name:= fmt.Sprintf(“%s / backup_folder_%v.tar.gz”,path,time.Now()。Unix())
file,err:= os.OpenFile  (名称,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  。等待();  err!= nil {
 return err 
} 
 
return nil 
   
 
 

我不了解cmd变量和io.Copy之间的关系,其中 以及它如何知道要复制哪个文件。 我喜欢使用io.Copy的想法,但是我不知道如何通过ssh创建文件并开始使用io.Copy向其发送内容。

  • 写回答
  • 好问题 提建议
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dtot74529 2018-11-12 08:52
    已采纳

    Here is a minimal example on how to use Go as an scp client:

    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
    ", stat.Size(), "filecopyname")
        io.Copy(hostIn, file)
        fmt.Fprint(hostIn, "\x00")
        wg.Done()
    }()
    
    session.Run("/usr/bin/scp -t /remotedirectory/")
    wg.Wait()
    

    Note that I have ignored all errors only for conciseness.

    1. session.StdinPipe() will create a writable pipe for the remote host.
    2. fmt.Fprintf(... "C0664 ...") will signal the start of a file with 0664 permission, stat.Size() size and the remote filename filecopyname.
    3. io.Copy(hostIn, file) will write the contents of file into hostIn.
    4. fmt.Fprint(hostIn, "\x00") will signal the end of the file.
    5. session.Run("/usr/bin/scp -qt /remotedirectory/") will run the scp command.

    Edit: Added waitgroup per OP's request

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题