安裝github.com/pkg/sftp
我們之前介紹了,golang如何通過ssh連接服務器執行命令,下面我們來如何上傳文件,上傳文件同樣需要之前的ssh,但是除此之外還需要一個模塊,直接使用go get github.com/pkg/sftp
安裝即可
使用
package main
import (
"fmt"
"github.com/pkg/sftp"
"golang.org/x/crypto/ssh"
"io"
"log"
"net"
"os"
"time"
)
//連接的配置
type ClientConfig struct {
Host string //ip
Port int64 // 端口
Username string //用戶名
Password string //密碼
sshClient *ssh.Client //ssh client
sftpClient *sftp.Client //sftp client
LastResult string //最近一次運行的結果
}
func (cliConf *ClientConfig) createClient(host string, port int64, username, password string) {
var (
sshClient *ssh.Client
sftpClient *sftp.Client
err error
)
cliConf.Host = host
cliConf.Port = port
cliConf.Username = username
cliConf.Password = password
cliConf.Port = port
config := ssh.ClientConfig{
User: cliConf.Username,
Auth: []ssh.AuthMethod{ssh.Password(password)},
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil
},
Timeout: 10 * time.Second,
}
addr := fmt.Sprintf("%s:%d", cliConf.Host, cliConf.Port)
if sshClient, err = ssh.Dial("tcp", addr, &config); err != nil {
log.Fatalln("error occurred:", err)
}
cliConf.sshClient = sshClient
//此時獲取了sshClient,下面使用sshClient構建sftpClient
if sftpClient, err = sftp.NewClient(sshClient); err != nil {
log.Fatalln("error occurred:", err)
}
cliConf.sftpClient = sftpClient
}
func (cliConf *ClientConfig) RunShell(shell string) string {
var (
session *ssh.Session
err error
)
//獲取session,這個session是用來遠程執行操作的
if session, err = cliConf.sshClient.NewSession(); err != nil {
log.Fatalln("error occurred:", err)
}
//執行shell
if output, err := session.CombinedOutput(shell); err != nil {
fmt.Println(shell)
log.Fatalln("error occurred:", err)
} else {
cliConf.LastResult = string(output)
}
return cliConf.LastResult
}
func (cliConf *ClientConfig) Upload(srcPath, dstPath string){
srcFile, _ := os.Open(srcPath) //本地
dstFile, _ := cliConf.sftpClient.Create(dstPath) //遠程
defer func() {
_ = srcFile.Close()
_ = dstFile.Close()
}()
buf := make([]byte, 1024)
for {
n, err := srcFile.Read(buf)
if err != nil {
if err != io.EOF {
log.Fatalln("error occurred:",err)
} else {
break
}
}
_, _ = dstFile.Write(buf[: n])
}
fmt.Println(cliConf.RunShell(fmt.Sprintf("ls %s", dstPath)))
}
func (cliConf *ClientConfig) Download(srcPath, dstPath string){
srcFile, _ := cliConf.sftpClient.Open(srcPath) //遠程
dstFile, _ := os.Create(dstPath) //本地
defer func() {
_ = srcFile.Close()
_ = dstFile.Close()
}()
if _, err := srcFile.WriteTo(dstFile); err != nil {
log.Fatalln("error occurred", err)
}
fmt.Println("文件下載完畢")
}
func main() {
cliConf := new(ClientConfig)
cliConf.createClient("xx.xx.xx.xx", 22, "root", "xxxxxx")
//本地文件上傳到服務器
cliConf.Upload(`D:\go\haha.go`, `/root/haha.go`) // /root/haha.go
//從服務器中下載文件
cliConf.Download(`/root/1.py`, `D:\go\1.py`) //文件下載完畢
}