使用go語言的第三方包:github.com/pkg/sftp和golang.org/x/crypto/ssh實現(xiàn)文件和文件夾傳輸。
1、創(chuàng)建connect方法:
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,
HostKeyCallback: ssh.InsecureIgnoreHostKey(), //ssh.FixedHostKey(hostKey),
}
// 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
}
2、上傳文件
func uploadFile(sftpClient *sftp.Client, localFilePath string, remotePath string) {
srcFile, err := os.Open(localFilePath)
if err != nil {
fmt.Println("os.Open error : ", localFilePath)
log.Fatal(err)
}
defer srcFile.Close()
var remoteFileName = path.Base(localFilePath)
dstFile, err := sftpClient.Create(path.Join(remotePath, remoteFileName))
if err != nil {
fmt.Println("sftpClient.Create error : ", path.Join(remotePath, remoteFileName))
log.Fatal(err)
}
defer dstFile.Close()
ff, err := ioutil.ReadAll(srcFile)
if err != nil {
fmt.Println("ReadAll error : ", localFilePath)
log.Fatal(err)
}
dstFile.Write(ff)
fmt.Println(localFilePath + " copy file to remote server finished!")
}
3、上傳文件夾
func uploadDirectory(sftpClient *sftp.Client, localPath string, remotePath string) {
localFiles, err := ioutil.ReadDir(localPath)
if err != nil {
log.Fatal("read dir list fail ", err)
}
for _, backupDir := range localFiles {
localFilePath := path.Join(localPath, backupDir.Name())
remoteFilePath := path.Join(remotePath, backupDir.Name())
if backupDir.IsDir() {
sftpClient.Mkdir(remoteFilePath)
uploadDirectory(sftpClient, localFilePath, remoteFilePath)
} else {
uploadFile(sftpClient, path.Join(localPath, backupDir.Name()), remotePath)
}
}
fmt.Println(localPath + " copy directory to remote server finished!")
}
4、上傳測試
func DoBackup(host string, port int, userName string, password string, localPath string, remotePath string) {
var (
err error
sftpClient *sftp.Client
)
start := time.Now()
sftpClient, err = connect(userName, password, host, port)
if err != nil {
log.Fatal(err)
}
defer sftpClient.Close()
_, errStat := sftpClient.Stat(remotePath)
if errStat != nil {
log.Fatal(remotePath + " remote path not exists!")
}
backupDirs, err := ioutil.ReadDir(localPath)
if err != nil {
log.Fatal(localPath + " local path not exists!")
}
uploadDirectory(sftpClient, localPath, remotePath)
elapsed := time.Since(start)
fmt.Println("elapsed time : ", elapsed)
}
補(bǔ)充:go實現(xiàn)ssh遠(yuǎn)程機(jī)器并傳輸文件
核心依賴包:
golang.org/x/crypto/ssh
github.com/pkg/sftp
其中g(shù)olang.org/x/crypto/ssh 可從github上下載,
下載地址:https://github.com/golang/crypto
ssh連接源碼(這里是根據(jù)秘鑰連接):
var keypath = "key/id_rsa"
//獲取秘鑰
func publicKey(path string) ssh.AuthMethod {
keypath, err := homedir.Expand(path)
if err != nil {
fmt.Println("獲取秘鑰路徑失敗", err)
}
key, err1 := ioutil.ReadFile(keypath)
if err1 != nil {
fmt.Println("讀取秘鑰失敗", err1)
}
signer, err2 := ssh.ParsePrivateKey(key)
if err2 != nil {
fmt.Println("ssh 秘鑰簽名失敗", err2)
}
return ssh.PublicKeys(signer)
}
//獲取ssh連接
func GetSSHConect(ip, user string, port int) (*ssh.Client) {
con := ssh.ClientConfig{
User: user,
Auth: []ssh.AuthMethod{publicKey(keypath)},
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
}
addr := fmt.Sprintf("%s:%d", ip, port)
client, err := ssh.Dial("tcp", addr, con)
if err != nil {
fmt.Println("Dail failed: ", err)
panic(err)
}
return client
}
// 遠(yuǎn)程執(zhí)行腳本
func Exec_Task(ip, user, localpath, remotepath string) int {
port := 22
client := GetSSHConect(ip, user, port)
UploadFile(ip, user, localpath, remotepath, port)
session, err := client.NewSession()
if err != nil {
fmt.Println("創(chuàng)建會話失敗", err)
panic(err)
}
defer session.Close()
remoteFileName := path.Base(localpath)
dstFile := path.Join(remotepath, remoteFileName)
err1 := session.Run(fmt.Sprintf("/usr/bin/sh %s", dstFile))
if err1 != nil {
fmt.Println("遠(yuǎn)程執(zhí)行腳本失敗", err1)
return 2
} else {
fmt.Println("遠(yuǎn)程執(zhí)行腳本成功")
return 1
}
}
文件傳輸功能:
//獲取ftp連接
func getftpclient(client *ssh.Client) (*sftp.Client) {
ftpclient, err := sftp.NewClient(client)
if err != nil {
fmt.Println("創(chuàng)建ftp客戶端失敗", err)
panic(err)
}
return ftpclient
}
//上傳文件
func UploadFile(ip, user, localpath, remotepath string, port int) {
client := GetSSHConect(ip, user, port)
ftpclient := getftpclient(client)
defer ftpclient.Close()
remoteFileName := path.Base(localpath)
fmt.Println(localpath, remoteFileName)
srcFile, err := os.Open(localpath)
if err != nil {
fmt.Println("打開文件失敗", err)
panic(err)
}
defer srcFile.Close()
dstFile, e := ftpclient.Create(path.Join(remotepath, remoteFileName))
if e != nil {
fmt.Println("創(chuàng)建文件失敗", e)
panic(e)
}
defer dstFile.Close()
buffer := make([]byte, 1024)
for {
n, err := srcFile.Read(buffer)
if err != nil {
if err == io.EOF {
fmt.Println("已讀取到文件末尾")
break
} else {
fmt.Println("讀取文件出錯", err)
panic(err)
}
}
dstFile.Write(buffer[:n])
//注意,由于文件大小不定,不可直接使用buffer,否則會在文件末尾重復(fù)寫入,以填充1024的整數(shù)倍
}
fmt.Println("文件上傳成功")
}
//文件下載
func DownLoad(ip, user, localpath, remotepath string, port int) {
client := GetSSHConect(ip, user, port)
ftpClient := getftpclient(client)
defer ftpClient.Close()
srcFile, err := ftpClient.Open(remotepath)
if err != nil {
fmt.Println("文件讀取失敗", err)
panic(err)
}
defer srcFile.Close()
localFilename := path.Base(remotepath)
dstFile, e := os.Create(path.Join(localpath, localFilename))
if e != nil {
fmt.Println("文件創(chuàng)建失敗", e)
panic(e)
}
defer dstFile.Close()
if _, err1 := srcFile.WriteTo(dstFile); err1 != nil {
fmt.Println("文件寫入失敗", err1)
panic(err1)
}
fmt.Println("文件下載成功")
}
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
您可能感興趣的文章:- golang-gin-mgo高并發(fā)服務(wù)器搭建教程
- golang HTTP 服務(wù)器 處理 日志/Stream流的操作
- golang項目如何上線部署到Linu服務(wù)器(方法詳解)
- 部署Django到阿里云服務(wù)器教程示例
- 解決啟動django,瀏覽器顯示“服務(wù)器拒絕訪問”的問題
- Nginx+Uwsgi+Django 項目部署到服務(wù)器的思路詳解