为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
德玛西亚99 2022-09-26 15:14:47
例如,当我在Go代码中执行普通命令时,它可以正常执行并返回结果:ls -ls// Error handling is omitted, in fact there is error handling in my codefunc 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 -lsstdout: total 84 -rw-r--r-- 1 root root 358 Aug 14 23:09 main.go4 -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 codefunc 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 osos.system("nsenter -n --target 24347")或者另一个问题,如何在Go中编写代码,以便我可以执行此代码以ssh到其他主机,我觉得这似乎是同样的问题。
查看完整描述

1 回答

?
摇曳的蔷薇

TA贡献1793条经验 获得超6个赞

你有几个问题。


首先,您正在尝试生成一个交互式命令(默认情况下将在目标命名空间中启动一个shell),但是您也将stdout连接到变量,这意味着即使它有效,您也无法在命令退出之前看到任何输出,这可能不是您想要的。nsenter


其次,您没有将stdin连接到任何有用的东西,这意味着大多数交互式命令将简单地退出。


要在 Go 中启动交互式子命令,可以编写如下内容:


package main


import (

    "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 main


import (

    "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


请注意,您可能更典型地使用模块中的方法:Outputexec


package main


import (

    "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))

}


查看完整回答
反对 回复 2022-09-26
  • 1 回答
  • 0 关注
  • 139 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号