Golang中如何获取远程变量

Golang中如何获取远程变量 以下是我的困境: 我正在开发一个 https://github.com/cdr/sshcode 的分支,目标是使其支持 Windows 系统 https://github.com/Merith-TK/sshcode/tree/msys-support

问题是,当 Windows 发送路径时,我已将问题缩小到 Windows 将路径字符串作为 字面量 路径发送。 因此,路径 ~/whatever 会以 '~'/whatever 的形式发送,这在技术上是“有效”的路径。

我想在代码中实现一个检查:

if runtime.GOOS = windows {
    // 获取远程 $HOME 变量
    // 在所有字符串中将 ~ 替换为 $HOME
}

更多关于Golang中如何获取远程变量的实战教程也可以访问 https://www.itying.com/category-94-b0.html

9 回复

查阅文档,还有其他方法,例如:

  • os.LookupEnv
  • os.Getenv

更多关于Golang中如何获取远程变量的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


好的……也许使用 os.Environ() 可以解决问题……

func main() {
    fmt.Println("hello world")
}

是的,我能理解那部分,这正是我打算使用的。但问题在于如何从 Linux 服务器获取 $HOME。 (这正是所需的代码。)

我需要帮助从服务器拉取 $HOME(除了通过 SSH,无法在服务器上运行任何代码)。

在我看来,您想要创建一种远程命令服务器。例如,在客户端机器上,我会向该服务器发送一个命令,然后该命令在远程机器上执行。如果是这样,最简单的方法是创建一个 HTTP 服务器,通过 URL 接收命令… 请告诉我,我是否完全理解了您想要做的事情…

有一个 runtime 包,你可以检查是否在 Windows 上运行。类似这样:

package main

import (
    "fmt"
    "runtime"
)

func main() {

    if runtime.GOOS == "windows" {
        fmt.Println("You are running on Windows")
    } else {
        fmt.Println("You are running on an OS other than Windows")
    }
}

(*user.User).HomeDir 是否满足你的需求? https://golang.org/pkg/os/user/

// 示例代码:获取用户主目录
package main

import (
    "fmt"
    "os/user"
)

func main() {
    usr, err := user.Current()
    if err != nil {
        panic(err)
    }
    fmt.Println("Home directory:", usr.HomeDir)
}

@Yamil_Bracho 这有点违背程序初衷,但至少是可行的,因为 sshcode 已经拉取了一个二进制文件来执行,然后再通过 sshproxy 传回。

@skillian 问题是,就我所知,按照我使用它的方式,我只能获取到客户端的 HomeDir,而不是服务器的。

你知道我如何在远程机器上执行这个吗?

GitHub图标 GitHub

头像

sfreiberg/simplessh

一个围绕 Go 语言中 ssh 和 sftp 库的简单抽象。 - sfreiberg/simplessh

这看起来似乎能够实现我想要的功能。

在Golang中获取远程环境变量可以通过SSH会话执行命令来实现。以下是针对Windows环境的实现示例:

package main

import (
    "fmt"
    "runtime"
    "strings"
    "golang.org/x/crypto/ssh"
)

func getRemoteHome(sshClient *ssh.Client) (string, error) {
    // 创建SSH会话
    session, err := sshClient.NewSession()
    if err != nil {
        return "", err
    }
    defer session.Close()

    // 执行获取HOME环境变量的命令
    // Windows使用echo %USERPROFILE%,Unix-like系统使用echo $HOME
    var cmd string
    if runtime.GOOS == "windows" {
        cmd = "echo %USERPROFILE%"
    } else {
        cmd = "echo $HOME"
    }

    // 执行命令并获取输出
    output, err := session.Output(cmd)
    if err != nil {
        return "", err
    }

    // 清理输出(去除换行符和空格)
    home := strings.TrimSpace(string(output))
    return home, nil
}

func replaceTildeWithHome(path, home string) string {
    return strings.Replace(path, "~", home, 1)
}

func main() {
    // SSH连接配置示例
    config := &ssh.ClientConfig{
        User: "username",
        Auth: []ssh.AuthMethod{
            ssh.Password("password"),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }

    // 建立SSH连接
    client, err := ssh.Dial("tcp", "remote-host:22", config)
    if err != nil {
        fmt.Printf("连接失败: %v\n", err)
        return
    }
    defer client.Close()

    // 获取远程HOME目录
    remoteHome, err := getRemoteHome(client)
    if err != nil {
        fmt.Printf("获取远程HOME失败: %v\n", err)
        return
    }

    fmt.Printf("远程HOME目录: %s\n", remoteHome)

    // 示例:替换路径中的~
    testPath := "~/project/file.txt"
    newPath := replaceTildeWithHome(testPath, remoteHome)
    fmt.Printf("原始路径: %s\n", testPath)
    fmt.Printf("替换后路径: %s\n", newPath)
}

对于Windows特定的路径处理,可以这样实现:

func fixWindowsPath(path string, sshClient *ssh.Client) (string, error) {
    if runtime.GOOS != "windows" {
        return path, nil
    }

    // 检查路径是否以~开头
    if strings.HasPrefix(path, "~") {
        home, err := getRemoteHome(sshClient)
        if err != nil {
            return path, err
        }
        
        // 替换开头的~为HOME目录
        path = strings.Replace(path, "~", home, 1)
    }
    
    return path, nil
}

如果需要在现有代码中集成,可以这样使用:

func handlePath(originalPath string, sshClient *ssh.Client) string {
    if runtime.GOOS == "windows" && strings.Contains(originalPath, "~") {
        home, err := getRemoteHome(sshClient)
        if err != nil {
            // 处理错误,可以返回原始路径或记录日志
            return originalPath
        }
        
        // 替换所有~为HOME目录
        return strings.ReplaceAll(originalPath, "~", home)
    }
    return originalPath
}

注意:实际使用时需要根据sshcode项目的具体结构调整SSH客户端的获取方式。

回到顶部