如何使用Golang执行”top”命令的输出

huangapple go评论109阅读模式
英文:

How to execute 'top' Command output using Golang

问题

我想将"top"命令的输出写入另一个文件。但是当我尝试使用下面的代码时,我得到了以下错误:

'exit status 1'。

以下是我的代码:

  1. package main
  2. import "os/exec"
  3. func main() {
  4. app := "top"
  5. cmd := exec.Command(app)
  6. stdout, err := cmd.Output()
  7. if err != nil {
  8. println(err.Error())
  9. return
  10. }
  11. print(string(stdout))
  12. }

非常感谢您的帮助。提前感谢。

英文:

I want to write the 'top' command's output to another file. But when I tried it with the below code, I get the below error:

'exit status 1'.

Here is my code:

  1. package main
  2. import "os/exec"
  3. func main() {
  4. app := "top"
  5. cmd := exec.Command(app)
  6. stdout, err := cmd.Output()
  7. if err != nil {
  8. println(err.Error())
  9. return
  10. }
  11. print(string(stdout))
  12. }

Any help is greatly appreciated. Thanks in advance.

答案1

得分: 2

从“top”命令的手册页面来看,-b选项适用于将输出发送到另一个程序(无颜色,无任何格式),作为纯文本输出,-n选项表示在停止之前迭代的次数。如果没有使用-n选项,它将无限次迭代。

  1. func main() {
  2. app := "top"
  3. arg0 := "-b"
  4. arg1 := "-n"
  5. arg2 := "1"
  6. cmd := exec.Command(app, arg0, arg1, arg2)
  7. stdout, err := cmd.Output()
  8. if err != nil {
  9. println(err.Error())
  10. return
  11. }
  12. print(string(stdout))
  13. }

以上是一个示例代码,它使用了上述的选项来执行"top"命令,并将输出作为纯文本输出。

英文:

From man page for "top", -b option is good for sending output to another program (no color, no anything) as plain text, and -n is the number of frame it will iterate before stopping. Without -n it will iterate infinite time.

  1. func main() {
  2. app := "top"
  3. arg0 := "-b"
  4. arg1 := "-n"
  5. arg2 := "1"
  6. cmd := exec.Command(app, arg0, arg1, arg2)
  7. stdout, err := cmd.Output()
  8. if err != nil {
  9. println(err.Error())
  10. return
  11. }
  12. print(string(stdout))
  13. }

答案2

得分: 2

s := fmt.Sprintf("top -bn2 | fgrep 'Cpu(s)' | tail -1", host)
log.Printf("top = %s\n", s)
cmd := exec.Command("bash", "-c", s)
b, e := cmd.Output()
if e != nil {
log.Printf("failed due to :%v\n", e)
panic(e)
}
log.Printf("%v\n", string(b))
raw := string(b)

如果你计划以批处理模式运行top命令,你可以这样做。注意,如果你只想获取最后一个结果而不是捕获所有结果,可以使用tail -1命令,如果你想要筛选特定字段,可以使用fgrep命令,但这不是必需的。

以下是其他运行top命令的方法。

c := exec.Command("top")
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
c.Run()
这是用于本地运行。如果你通过ssh查看,请使用以下命令 -

c := exec.Command("ssh", "-t", "localhost", "top")
c.Stdin = os.Stdin
c.Stdout = os.Stdout
c.Stderr = os.Stderr
c.Run()

如果你想要启动一个服务器,并通过telnet作为客户端连接,并在telnet屏幕上显示top命令的结果(可能是通过使用Go内省服务器远程运行top的常见情况),请使用以下代码 -

func main() {
l, _ := net.Listen("tcp", "127.0.0.1:12345")
for {
c, _ := l.Accept()
go func() {
handle(&c)
}()
}
}
func handle(c *net.Conn) {
cmd := exec.Command("top")
cstdout, _ := cmd.StdoutPipe()
go io.Copy(bufio.NewWriter(*c), bufio.NewReader(cstdout))
cmd.Run()
}

如果你正在构建一个终端,使用telnet和ssh运行通用命令(如应用程序),请使用这个库 - https://github.com/kr/pty

编辑 让它更好...这里有一个使用PTY的示例,场景是如果你使用ssh -t运行一个命令,并希望通过telnet从这个服务器类型的设置进行交互,例如top,请使用以下代码:

cmd := exec.Command("ssh", "-t", "localhost", "top")
f, _ := pty.Start(cmd)
go io.Copy(bufio.NewWriter(*c), f)
go io.Copy(f, bufio.NewReader(*c))
go io.Copy(bufio.NewWriter(*c), os.Stdin)
cmd.Run()

英文:
  1. s := fmt.Sprintf(`"top -bn2 | fgrep 'Cpu(s)' | tail -1"`, host)
  2. log.Printf("top = %s\n", s)
  3. cmd := exec.Command("bash", "-c", s)
  4. b, e := cmd.Output()
  5. if e != nil {
  6. log.Printf("failed due to :%v\n", e)
  7. panic(e)
  8. }
  9. log.Printf("%v\n", string(b))
  10. raw := string(b)

This is what you could potentially do if you are planning to run top in batch mode. Note tail -1 maybe of value if you wanted to pick last one instead of capturing everything, and fgrep useful if you are to grep for a specific fields - however it is not necessary.

For reference, here are other ways to run top.

  1. c := exec.Command("top")
  2. c.Stdin = os.Stdin
  3. c.Stdout = os.Stdout
  4. c.Stderr = os.Stderr
  5. c.Run()

This is for local. If you are looking via ssh, use this -

  1. c := exec.Command("ssh", "-t", "localhost", "top")
  2. c.Stdin = os.Stdin
  3. c.Stdout = os.Stdout
  4. c.Stderr = os.Stderr
  5. c.Run()

If you want to start a server, and connect as a client via telnet and show on telnet screen result of top command (common case when running top remotely using a go introspecting server perhaps) use this -

<pre>
<code>

  1. func main() {
  2. l, _ := net.Listen(&quot;tcp&quot;, &quot;127.0.0.1:12345&quot;)
  3. for {
  4. c, _ := l.Accept()
  5. go func() {
  6. handle(&amp;c)
  7. }()
  8. }
  9. }
  10. func handle(c *net.Conn) {
  11. cmd := exec.Command(&quot;top&quot;)
  12. cstdout, _ := cmd.StdoutPipe()
  13. go io.Copy(bufio.NewWriter(*c), bufio.NewReader(cstdout))
  14. cmd.Run()
  15. }

</code>
</pre>

If you are building a terminal using telnet and ssh to run generic commands like app use this library - https://github.com/kr/pty

Edit Going to make it better ... here's an example that works for PTY, scenario is if you use ssh -t to run a command want to interact with telneting from this server type setup e.g. top use this :

<pre>
<code>

  1. cmd := exec.Command(&quot;ssh&quot;, &quot;-t&quot;, &quot;localhost&quot;, &quot;top&quot;)
  2. f, _ := pty.Start(cmd)
  3. go io.Copy(bufio.NewWriter(*c), f)
  4. go io.Copy(f, bufio.NewReader(*c))
  5. go io.Copy(bufio.NewWriter(*c), os.Stdin)
  6. cmd.Run()

</code>
</pre>

huangapple
  • 本文由 发表于 2016年11月17日 20:39:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/40655133.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定