目的:在go语言中ssh连接服务器,上传shell文件并执行

代码:

import 	"golang.org/x/crypto/ssh"
func InitHardware(username string, password string, ip string, ipv6 string, port int, arch string, ipStack string, classType string, classVersion string) error {
	logger.Debug("start InitHardware:", ip, port)

	installBootstrap := "xxx.sh" //自己的脚本文件名
	fullpath := path.Join(util.GetRootDir(), "sbin", installBootstrap) //脚本文件所在目录
	installBootstrapUrl := configure.GetBootstrapPackageUrl()
	if arch == "aarch64" { //判断机器架构以便替换文件url
		installBootstrapUrl = strings.Replace(installBootstrapUrl, "/x86_64/", "/aarch64/", 1)
	}
	//连接配置
	config := &ssh.ClientConfig{
		User: username,
		Auth: []ssh.AuthMethod{
			ssh.Password(password),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}
	if len(ipv6) > 0 && ipv6 != "" {
		ip = "[" + ipv6 + "]"
	}
	conn, err := ssh.Dial("tcp", ip+":"+strconv.Itoa(port), config)
	if err != nil {
		return err
	}
	defer func(conn *ssh.Client) {
		err := conn.Close()
		if err != nil {
		}
	}(conn)

	session, err := conn.NewSession()
	if err != nil {
		return err
	}
	defer func(session *ssh.Session) {
		err := session.Close()
		if err != nil {
		}
	}(session)

	// 执行 "echo $HOME" 命令以获取用户目录
	var stdoutBuf strings.Builder
	session.Stdout = &stdoutBuf
	err = session.Run("echo $HOME")
	if err != nil {
		logger.Errorf("get user dir, error: error=%s", err)
		return err
	}
	// 获取用户目录并删除末尾的换行符
	userDir := strings.TrimSpace(stdoutBuf.String())

	contents, err := os.ReadFile(fullpath)
	if err != nil {
		logger.Errorf("read shell file, error: fullpath=%s, error=%s", fullpath, err)
		return err
	}
	// 上传 shell 文件到远程服务器
	remoteShellFile := path.Join(userDir, installBootstrap)
	session1, err := conn.NewSession()
	if err != nil {
		return err
	}
	defer session1.Close()
	var b bytes.Buffer
	session1.Stdout = &b
	err = session1.Run(fmt.Sprintf("echo '%s' > %s", contents, remoteShellFile))
	if err != nil {
		logger.Errorf("upload shell file, error: remoteShellFile=%s, error=%s", remoteShellFile, err)
		return err
	}

	session2, err := conn.NewSession()
	if err != nil {
		return err
	}
	defer func(session2 *ssh.Session) {
		err := session2.Close()
		if err != nil {
		}
	}(session2)
	session2.Stdout = os.Stdout
	session2.Stderr = os.Stderr
	logger.Infof("==========ipv6test==========")

	logger.Infof(fmt.Sprintf("sh %s %s %s %s %s %s", remoteShellFile, installBootstrapUrl, woodpeckerRpc, cmdRpc, emsRpc, ipStack))

	err = session2.Run(fmt.Sprintf("sh %s %s %s %s %s %s %s %s", remoteShellFile, installBootstrapUrl, woodpeckerRpc, cmdRpc, emsRpc, ipStack, classType, classVersion))
	if err != nil {
		logger.Errorf("InitHardware ip:%s, error: ", ip, session2.Stderr)
		return err
	}
	return nil
}