Golang Go语言中 exec.Cmd 中对于标准输入输出流重定向的问题
学习项目,目标是实现一个简单的 telnet 功能(远程执行命令)。但是第一步就出现了问题。主要代码如下:
https://gist.github.com/Lua12138/7cf05e84ee30adde582f78f0c4a62103
通过这样的代码,我发现,如果执行不需要交互的命令,一切都符合预期,但执行需要交互命令行,比如 bash/base64 这样的命令行,就出现了预期外结果。
如果执行 bash ,那么在客户端(下半部分代码),后续输入任何命令行都会提示: not found/sh: <stdin>[2]: ls
,而其他命令,应该如何通过网络发送过去^D 这样的控制符呢。
Golang Go语言中 exec.Cmd 中对于标准输入输出流重定向的问题
更多关于Golang Go语言中 exec.Cmd 中对于标准输入输出流重定向的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你可能需要一个 tty
https://github.com/creack/pty
更多关于Golang Go语言中 exec.Cmd 中对于标准输入输出流重定向的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
#1 感谢大佬。仔细排查后,是系统原因。由于客户端是在 Windows 下运行,因此 stdin 被转发到对端以后,Linux 解析命令行以\n 分隔,但是 Windows 中以\r\n 作为分隔,因此 Linux 最终得到类似这样的命令参数 ls\r ,所以出现了找不到命令的情况。
在Golang中,使用exec.Cmd
结构可以方便地执行外部命令,并对其进行标准输入输出流的重定向。这是通过Cmd
结构中的Stdin
、Stdout
和Stderr
字段来实现的。
重定向标准输入(Stdin)通常用于向子进程提供输入数据。你可以通过将os.Stdin
(或其他io.Reader
实现)赋值给Cmd.Stdin
来实现这一点。例如,如果你有一个文件,并希望将其内容作为子进程的输入,可以使用os.Open
打开文件,然后将返回的文件句柄赋值给Cmd.Stdin
。
重定向标准输出(Stdout)用于捕获子进程的输出。你可以将Cmd.Stdout
设置为一个io.Writer
接口的实现,如os.Stdout
(将输出打印到控制台)或一个文件句柄(将输出保存到文件)。
重定向标准错误(Stderr)的方法与重定向标准输出类似,也是通过设置Cmd.Stderr
来实现的。
在实际操作中,为了确保重定向正确,你通常需要在调用Cmd.Run()
或Cmd.Start()
之前完成这些设置。此外,如果子进程需要交互式输入,你可能需要使用Cmd.StdinPipe()
和Cmd.StdoutPipe()
来创建管道,并通过goroutine来读取和写入这些管道,以实现双向通信。
总的来说,Golang的exec
包提供了强大的功能来执行外部命令,并通过标准输入输出流的重定向来与这些命令进行交互。