以前有一篇介紹如何使用 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