以前有一篇介绍如何使用 golang 经过SSH协议来执行远程命令:golang执行远程命令 一样,经过SSH协议也能够使用 golang 来远程传输文件。git
除了 SSH 的库,为了传输文件,还须要用到 github.com/pkg/sftp 这个库。github
废话很少说,直接看代码。 因为是基于 SSH 协议实现的远程文件传输,因此先建立 SSH 的链接,再建立传输文件的 sftp 客户端。golang
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
func
connect(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,
}
// 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
}
|
使用上面的 connect 方法建立 sftpClient 后,发送文件很简单。app
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
package
main
import
(
"fmt"
"log"
"os"
"path"
"time"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
)
func
main() {
var
(
err error
sftpClient *sftp.Client
)
// 这里换成实际的 SSH 链接的 用户名,密码,主机名或IP,SSH端口
sftpClient, err = connect(
"root"
,
"rootpass"
,
"127.0.0.1"
,
22
)
if
err != nil {
log.Fatal(err)
}
defer
sftpClient.Close()
// 用来测试的本地文件路径 和 远程机器上的文件夹
var
localFilePath =
"/path/to/local/file/test.txt"
var
remoteDir =
"/remote/dir/"
srcFile, err := os.Open(localFilePath)
if
err != nil {
log.Fatal(err)
}
defer
srcFile.Close()
var
remoteFileName = path.Base(localFilePath)
dstFile, err := sftpClient.Create(path.Join(remoteDir, remoteFileName))
if
err != nil {
log.Fatal(err)
}
defer
dstFile.Close()
buf := make([]byte,
1024
)
for
{
n, _ := srcFile.Read(buf)
if
n ==
0
{
break
}
dstFile.Write(buf)
}
fmt.Println(
"copy file to remote server finished!"
)
}
|
从远程机器上获取文件的方式略有不一样,但也很简单。ssh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
package
main
import
(
"fmt"
"log"
"os"
"path"
"time"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
)
func
main() {
var
(
err error
sftpClient *sftp.Client
)
// 这里换成实际的 SSH 链接的 用户名,密码,主机名或IP,SSH端口
sftpClient, err = connect(
"root"
,
"rootpass"
,
"127.0.0.1"
,
22
)
if
err != nil {
log.Fatal(err)
}
defer
sftpClient.Close()
// 用来测试的远程文件路径 和 本地文件夹
var
remoteFilePath =
"/path/to/remote/path/test.txt"
var
localDir =
"/local/dir"
srcFile, err := sftpClient.Open(remoteFilePath)
if
err != nil {
log.Fatal(err)
}
defer
srcFile.Close()
var
localFileName = path.Base(remoteFilePath)
dstFile, err := os.Create(path.Join(localDir, localFileName))
if
err != nil {
log.Fatal(err)
}
defer
dstFile.Close()
if
_, err = srcFile.WriteTo(dstFile); err != nil {
log.Fatal(err)
}
fmt.Println(
"copy file from remote server finished!"
)
}
|
上面的例子只是演示了文件传输,传输文件夹也很简单,只是多了遍历文件夹和建立文件夹的步骤,具体的函数能够自行查看 sftp 库中doc。tcp