【问题标题】:How to correctly emulate terminal in linux/macOS using exex(go)?如何使用 exex(go) 在 linux/macOS 中正确模拟终端?
【发布时间】:2020-09-09 11:45:06
【问题描述】:

我需要在go 中模拟一个终端。我尝试这样做:

lsCmd := exec.Command("bash", "-c", "ls")
lsOut, err := lsCmd.Output()
if err != nil {
    panic(err)
}
fmt.Println(string(lsOut))

而且它似乎工作正常(原生 ubuntu 终端显示一个水平列表,这个函数的结果是垂直的)。

但如果我专门调用了错误的命令,例如exec.Command ("bash", "-c", "lss"),我会得到:

恐慌:退出状态 127

在本地 ubuntu 终端中,我得到以下结果:

找不到命令“lss”,您的意思是:

和命令的枚举。

我需要与原生终端通信,如果我在标准的ubuntu终端中编写命令,得到与命令结果相同的结果。

最好的方法是什么?也许exec 库不适合这个?所有这些对于与 OS 终端的前端通信都是必需的。在一个简单的html/css/js页面上,用户输入一个命令,go之后发送到操作系统的本机终端,并将结果返回给前端。

如何获得与在本机终端中工作一样的执行命令结果?

【问题讨论】:

标签: go terminal-emulator


【解决方案1】:

问题

但如果我专门调用了错误的命令,例如 exec.Command (“bash”,“-c”,“lss”),我得到:

panic: exit status 127

在原生 ubuntu 终端中,我得到以下结果:

Command 'lss' not found, did you mean:

和命令的枚举。

这和Go无关,问题其实是两方面的:

  • Ubuntu 附带了一个特殊的包,command-not-found,它通常是预先安装的,它试图通过采用两种技术使终端对普通人更友好:

    • 它会尝试对拼写错误提出更正建议(您的情况)。
    • 当用户尝试执行某个程序时,它会尝试建议要安装的程序包,如果用户安装了特定的程序包,该程序将可用。
  • 当找不到命令时,“普通”(见下文)shell 通过返回非零退出代码来失败尝试。
    这是完全可以预料和正常的。 我的意思是,对此感到恐慌是绝对不明智的。

  • 在 Unix 系统上运行 shell 的方式存在历史差异。

    当用户登录系统时(请记住,在 shell 概念被发明的日子里,您将通过 hardware computer terminal 登录,这基本上就是您的 GNOME 终端窗口,但在硬件中,并且已连接通过电线), 启动所谓的登录shell
    逻辑外壳的主要思想是为用户提供交互式环境。

    但您肯定知道,shell 也能够执行脚本。 当 shell 执行脚本时,它以非交互模式运行。

Unix shell 可以工作的模式

现在让我们更深入地研究交互式与非交互式 shell。

  • 在交互模式下:

    • shell 通常连接到真实终端(hadrware 或terminal emulator;您的 GNOME 终端窗口是终端模拟器)。
      “已连接”表示shell的standard I/O streams与终端相连,这样shell打印的内容就会被终端显示出来。
    • 它为用户启用了某些花里胡哨的功能,通常提供有限的方法来编辑正在输入的内容(例如,bash 使用 GNU readline
  • 在非交互模式下:

    • Shell 的标准 I/O 流连接到某些文件(或“无处”,例如 /dev/null)。
    • 没有启用任何花里胡哨的功能 - 因为没有人可以使用它们。

GNU bash 能够在两种模式下运行,它运行在哪种模式下取决于 在how it was invoked.

在不同模式下初始化时,bash 读取不同的初始化脚本, 这解释了为什么 command-not-found 包提供的机器会进入交互模式,而在运行 bash 时不会否则——就像你从 Go 调用一样。

如何解决问题

最简单的尝试是使用 --login 命令行选项运行 bash,或者让它认为它作为交互式 shell 运行。

这可能会解决您的问题,但不一定。
下一个可能的问题是 一些 程序确实会检查它们是否在终端上运行 - 通常这些程序坚持与用户进行真正的交互,通常是出于安全目的,并且有些程序会没有连接到真实终端时根本无法运行——这些是“全屏”文本 UI 程序,例如 GNU Midnight Commander、Vim、Emacs、GNU Nano 和类似的任何东西。

要解决这个问题,唯一的解决方案是在伪终端环境中运行 shell,这就是 @eudore 在他们的评论中暗示的。
github.com/creack/pty 可能是一个开始查看的包; golang.org/x/crypto/ssh 还提供了一些与 PTY 争吵的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-02
    • 2018-05-29
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    • 2023-02-01
    • 1970-01-01
    相关资源
    最近更新 更多