Go语言通过ssh传文件并执行报错Text file busy

zhuiai 发布于 03/10 17:02
阅读 212
收藏 0
Go

【DevOps必读】产品经理与程序员之间如何破局?>>>

package main

import (
	"fmt"
	"log"
	"os"
	"path"
	"time"

	"github.com/pkg/sftp"
	"golang.org/x/crypto/ssh"
)

func sshconnect(user, password, host string, port int) (*ssh.Session, error) {
	var (
		auth         []ssh.AuthMethod
		addr         string
		clientConfig *ssh.ClientConfig
		client       *ssh.Client
		session      *ssh.Session
		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(),
	}

	// connet to ssh
	addr = fmt.Sprintf("%s:%d", host, port)

	if client, err = ssh.Dial("tcp", addr, clientConfig); err != nil {
		return nil, err
	}

	// create session
	if session, err = client.NewSession(); err != nil {
		return nil, err
	}

	return session, nil
}

func sftpconnect(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(),
	}

	// 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
}

func main() {
	session, err := sshconnect("root", "aaa111222", "47.97.111.111", 22)
	if err != nil {
		log.Fatal(err)
	}
	defer session.Close()
	session.Stdout = os.Stdout
	session.Stderr = os.Stderr
	session.Run("ls")
	fmt.Println("aq2.cn aaaaaaaa")

	var (
		sftpClient *sftp.Client
	)

	// 这里换成实际的 SSH 连接的 用户名,密码,主机名或IP,SSH端口
	sftpClient, err = sftpconnect("root", "aaa111222", "47.97.111.111", 22)
	if err != nil {
		log.Fatal(err)
	}
	defer sftpClient.Close()

	// 用来测试的本地文件路径 和 远程机器上的文件夹
	var localFilePath = "/opt/dev/aq2.cn/file"
	var remoteDir = "/opt/dev/aq2.cn/"
	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[0:n])
	}

	fmt.Println("copy file to remote server finished!")
	time.Sleep(10 * time.Second)

	session1, err := sshconnect("root", "aaa111222", "47.97.111.111", 22)
	if err != nil {
		log.Fatal(err)
	}
	defer session1.Close()
	session1.Stdout = os.Stdout
	session1.Stderr = os.Stderr
	session1.Run("chmod 755 /opt/dev/aq2.cn/file;nohup /opt/dev/aq2.cn/file &")
	fmt.Println("aq2.cn bbbbbbbbb")
}

有GO大佬能解决下吗?咋回事??

加载中
0
OH-小
OH-小

把你要替换的程序的进程关掉后再传

zhuiai
zhuiai
是程序在传文件sftp,不知道咋关!
返回顶部
顶部