V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
toomlo
V2EX  ›  Go 编程语言

为什么 go 执行命令时,获取不了 Telnet 的输出

  •  
  •   toomlo · 2020-10-26 01:53:33 +08:00 · 2957 次点击
    这是一个创建于 1489 天前的主题,其中的信息可能已经有所发展或是发生改变。

    因为一些原因,需要用 go 执行无交互的 Telnet命令并获取输出的数据

    命令是这样:

    (echo "keys *"; sleep 0.02) | telnet 127.0.0.1 6379
    

    直接在终端下执行,返回如下:

    https://i.imgur.com/qMU7vYG.png

    然后我写了下面的代码来测试

    //main.go
    package main
    
    import (
    	"bytes"
    	"flag"
    	"os/exec"
    )
    
    func main(){
    	c := flag.String("c", "ifconfig", "ifconfg")
    	flag.Parse()
    
    	var cmd *exec.Cmd
    	var stdout bytes.Buffer
    	var stderr bytes.Buffer
    	
    	cmd = exec.Command("bash", "-c", *c)
    	cmd.Stdout = &stdout
    	cmd.Stderr = &stderr
    
    	err := cmd.Run()
    	if err == nil {
    		print(stdout.String())
    	} else {
    		print(stderr.String())
    	}
    }
    
    

    执行命令:

    go run main.go -c "(echo \"keys *\"; sleep 0.02) | telnet 127.0.0.1 6379"
    

    输出的内容为:Connection closed by foreign host.

    我最后测试下面这条命令后,上面的程序就可以成功获取到直接在终端下执行非交互命令的输出了

    go run main.go -c "(echo \"keys *\"; sleep 0.02) | telnet 127.0.0.1 6379" > 1.txt; cat 1.txt; rm 1.txt
    

    https://i.imgur.com/6LghpDl.png

    上面的实际上是将 Telnet 的输出写入到文件里面,然后 cat 这个文件(cat 是标准输出),golang 执行命令的话就能获取到了

    还有没有同学有更优雅的命令来实现 golang 读取 Telnet 的输出啊(不改 go 代码) 先谢谢了~~~

    第 1 条附言  ·  2020-10-26 14:57:31 +08:00

    问题解决了

    因为sleep导致执行的命令不是正常退出的,所以err不等于nil 导致go输出的是stderr.String()

    实际上Telnet的标准输出在stdout.String()里面

    14 条回复    2020-10-27 18:23:06 +08:00
    Phant0m
        1
    Phant0m  
       2020-10-26 03:58:56 +08:00 via iPhone
    把 sleep 换成 exit 就行了
    eudore
        2
    eudore  
       2020-10-26 08:36:22 +08:00
    telnet 的效果 net.Dial 不就行了吗?
    oott123
        3
    oott123  
       2020-10-26 09:08:50 +08:00 via Android
    我觉得你在连 redis 服务器
    那么直接用 go 的 redis 客户端库不好吗
    GopherDaily
        4
    GopherDaily  
       2020-10-26 09:52:21 +08:00
    Search ``golang exec pipe``
    mengzhuo
        5
    mengzhuo  
       2020-10-26 09:54:43 +08:00
    端口通不通,用 net 包他不香么
    monkeyWie
        6
    monkeyWie  
       2020-10-26 10:31:53 +08:00   ❤️ 1
    标准输出和错误输出复用一个 buffer 就行了,已测试通过
    40EaE5uJO3Xt1VVa
        7
    40EaE5uJO3Xt1VVa  
       2020-10-26 10:49:27 +08:00
    如果只是单纯的测端口通不通,net 包应该够用了,要调 ifconfig 干嘛
    toomlo
        8
    toomlo  
    OP
       2020-10-26 14:48:06 +08:00
    @oott123 #3
    @eudore #2

    因为我这个是在极端环境下需要用到~~~所以才来问嘛,/哭哭
    toomlo
        9
    toomlo  
    OP
       2020-10-26 14:50:30 +08:00
    @monkeyWie #6 原谅我太菜了,感谢!!!
    popvlovs
        10
    popvlovs  
       2020-10-26 19:58:07 +08:00
    测连通性我一般用这个:echo > /dev/tcp/$ip/$port
    labulaka521
        11
    labulaka521  
       2020-10-26 22:23:17 +08:00 via iPhone
    我记着有个方法可以获取全部支持
    zunceng
        12
    zunceng  
       2020-10-27 09:22:57 +08:00
    telnet 太麻烦了 你用 redis-cli 也要好一点
    labulaka521
        13
    labulaka521  
       2020-10-27 10:29:15 +08:00
    CombinedOutput 可以获取全部输出
    toomlo
        14
    toomlo  
    OP
       2020-10-27 18:23:06 +08:00
    @labulaka521 #13 我之前用的这个,获取不了错误信息,比如你在终端执行一条不存在命令会提示命令不存在,但是 CombinedOutput 获取不了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1393 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:32 · PVG 01:32 · LAX 09:32 · JFK 12:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.