Go如何编写代码并执行系统命令以启动新终端?

例如,当我在Go代码中执行普通命令时,它可以正常执行并返回结果:ls -ls


// Error handling is omitted, in fact there is error handling in my code


func main() {

    for {

        var stdout bytes.Buffer

        cmd := exec.Command("sh","-c","ls -ls")

        cmd.Stdout = &stdout

        cmd.Run()

        fmt.Println(stdout.String())

    }

}

执行结果如下:


[root@10-x-x-xx /root]# go run main.go

/usr/bin/sh -c ls -ls

stdout: total 8

4 -rw-r--r-- 1 root root 358 Aug 14 23:09 main.go

4 -rw-r--r-- 1 root root 167 Aug 14 16:07 temp.yaml

但是当我执行命令来启动新终端时(不确定我的理解是否正确),程序会正常返回,没有错误,没有输出,也没有跳转到新终端。


例如:。这是一个用于输入网络命名空间的命令。通常,它将返回到“#”并成功输入。nsenter -n --target PID


// Error handling is omitted, in fact there is error handling in my code


func main() {

    for {

        var stdout bytes.Buffer

        cmd := exec.Command("sh","-c","nsenter -n --target 123")

        cmd.Stdout = &stdout

        cmd.Run()

        fmt.Println(stdout.String())

    }

}

程序在执行完成后退出,但实际上并不进入网络命名空间。


但是当我使用python时,没有这样的问题,它是可执行的。


import os

os.system("nsenter -n --target 24347")

或者另一个问题,如何在Go中编写代码,以便我可以执行此代码以ssh到其他主机,我觉得这似乎是同样的问题。


德玛西亚99
浏览 140回答 1
1回答

摇曳的蔷薇

你有几个问题。首先,您正在尝试生成一个交互式命令(默认情况下将在目标命名空间中启动一个shell),但是您也将stdout连接到变量,这意味着即使它有效,您也无法在命令退出之前看到任何输出,这可能不是您想要的。nsenter其次,您没有将stdin连接到任何有用的东西,这意味着大多数交互式命令将简单地退出。要在 Go 中启动交互式子命令,可以编写如下内容:package mainimport (    "os"    "os/exec")func main() {    cmd := exec.Command("bash", "--norc")    cmd.Stdout = os.Stdout    cmd.Stdin = os.Stdin    cmd.Stderr = os.Stderr    cmd.Env = os.Environ()    cmd.Env = append(cmd.Env, "PS1=example$ ")    cmd.Run()}(这将启动一个带有提示符的外壳程序bashexample$ )这里的关键是我们将 stdin、stdout 和 stderr 连接到父进程的相应描述符,这允许我们与子进程进行交互。如果您不打算启动交互式 shell,那么您现在拥有的内容将起作用。也就是说,您可以编写:package mainimport (    "bytes"    "fmt"    "os/exec")func main() {    var stdout bytes.Buffer    cmd := exec.Command("sudo", "nsenter", "-n", "--target", "2399896", "ip", "addr")    cmd.Stdout = &stdout    cmd.Run()    fmt.Println(stdout.String())}以上工作正常,并显示目标网络命名空间内运行的结果。ip addr请注意,您可能更典型地使用模块中的方法:Outputexecpackage mainimport (    "fmt"    "os/exec")func main() {    cmd := exec.Command("sudo", "nsenter", "-n", "--target", "2399896", "ip", "addr")    stdout, err := cmd.Output()    if err != nil {        panic(err)    }    fmt.Println(string(stdout))}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go