【问题标题】:Is it possible to open a new Linux terminal with a thread in C?是否可以用 C 语言打开一个新的 Linux 终端?
【发布时间】:2012-09-18 08:41:30
【问题描述】:

似乎有很多关于 SO 的问题很接近,但不是我想要的。我正在尝试查看是否有办法使用我的主程序中的线程/子进程打开一个新的终端窗口(Linux),并让该线程/子进程拥有新窗口。

只是对完整目标的概述:我将启动一个主程序,并将通过stdin 接受输入,如果我选择输入来“启动助手”,它将产生一个新的终端窗口它本身可以与用户交互(stdin/stdout)。

所以我想做的是让主程序调用线程,让线程使用/拥有新的终端窗口,然后在线程消失并死亡时关闭该窗口。

我知道这段代码不能正常工作,但从概念上讲,我想要这样的东西:

void * Runit()
{
    system("gnome-terminal"); //Would like to get a handle to this window
    while(1)
      printf("I'm the thread!!!\n"); //Would like to get this printed to the new window
}

int main()
{
    pthread_t child;
    pthread_create(&child, NULL, Runit, NULL);
    sleep(10);
    return 0; //Would like the child & its window to go away now.
}

对此的要求是宽松的,它不必是可移植的,这只是一个让我的生活更轻松的 Linux 小工具。它必须是 C 代码,所以除非该脚本可以从 C 运行,否则不能编写 shell 脚本。感谢任何帮助甚至其他想法。

编辑:

我知道在 linux 终端中有文件句柄 /dev/pts/x,我尝试过类似以下代码:

system("gnome-terminal");
sleep(2); //let the file handle show up in /dev/pts
fp = fopen("/dev/pts/<new file handler number>");
fprintf(fp, "echo hi");

句柄正确打开,但终端没有显示任何内容。

【问题讨论】:

  • 这个窗口应该运行一个shell吗?还是仅用于用户输入?
  • @parsifal - 只是 I/O(Ascii 菜单和响应),我不需要在新窗口中编写任何花哨的 shell 脚本
  • 这是经典的fork()execv()wait() 的东西。线程是不必要的。
  • @Dave - 除非我弄错了,否则不会这样做。我希望能够控制(即终止)生成的进程。工作线程或子线程将永远运行(打印/获取输入循环),所以我想从主线程中杀死它们。
  • 您显示的代码应该可以工作;我怀疑你正在犯 I/O 缓冲。请改用openwrite。也可以试试gnome-terminal -e 'sleep 36000'

标签: c linux multithreading terminal pthreads


【解决方案1】:

gnome-terminalxterm 都允许您在终端打开后运行任意命令。

因此,我建议您编写一个帮助程序,该程序知道如何与您的主程序通信(通过套接字、命名管道或其他一些 IPC 机制)。您的线程生成终端程序,将您的帮助程序传递给它,该程序将在终端内运行并通过上述 IPC 通道与线程通信。

【讨论】:

  • Your thread spawns the terminal program, passing it your helper program 我不明白这一点。如何将帮助程序“传递”到终端?这是我的问题的一部分,一旦终端启动,我不知道如何与终端通信。
  • 在命令行上:gnome-terminal -e helper,或xterm -c helper,如果有记忆的话。请注意,您不能可靠地给helper 本身提供命令行参数,也不能控制它的stdinstdout
  • 实际上,它的 xterm -e helper arguments... 并且您可以可靠地为其提供参数,尽管您不能(根据定义)将 stdin/stdout/stderr 更改为终端上的那些点(这是重点) .
【解决方案2】:

libvte,特别是vte_pty_* 函数,可能可以做你想做的事。

您提出问题的方式表明您不了解 Windows 和终端 I/O 在 Linux(或者实际上是一般的 Unix)下如何工作,因此我强烈建议您阅读这些内容。从 W. Richard Stevens 的书Unix 环境中的高级编程开始。

【讨论】:

  • 也许我没有。例如,我知道它们确实是文件句柄/dev/pts/X。而且我在想一旦打开一个新文件,获取它并打印到/从它打印应该是微不足道的......但它似乎不是。我会看看你提到的图书馆。
  • 我的印象是,您对终端设备的设想是倒退的。打开/dev/pts/X 会使您进入伪终端内部 的进程,而不是从伪终端接收 的进程。要成为伪终端接收的进程,请打开/dev/ptmx(然后跳过几个圈来为将在其中的进程设置pty)。
【解决方案3】:

据我了解,应用程序必须能够打印到终端中 - 但您是否也希望它能够从中读取?终端是否应该由用户控制?

我会使用终端的文件描述符进行操作,您应该检查终端从哪个文件获取用户输入(可能不是标准输入,而是一些 /dev/pts?),以及终端将其输出写入哪个文件,你可以捕获它,你也可以写入它,使内容显示在终端中。但请注意: 1)终端本身可能会启动shell(bash)-如果您写入/dev/pts,它将显示在终端中,但不会传递给终端中的bash进程-您无法远程发出命令在这样的终端, 2)我认为 /dev/pts/x 文件将在终端启动时创建,因此您不能 fork+dup+exec 并捕获终端输出 3) 将在终端中运行的进程也会打印一些输出 - 它不会从 /dev/pts 中读取

也许您需要用 C 编写应用程序,该应用程序将在终端中运行,并且该应用程序将与您拥有该终端的应用程序进行通信?

【讨论】:

  • 感谢您的意见。检查我对原始帖子的编辑。我相信这就是你的建议?我试过了,但它没有打印到屏幕上……看到有什么问题吗?
  • 谁知道发生了什么。在我的系统上,当我只打开两个 xterm 实例并在其中一个实例上 echo foo > /dev/pts/1 时,第二个实例中会显示“foo”。我不是unix专家,可能是某些终端不使用/dev/pts?
  • 有趣...实际上确实有效,将命令直接从一个窗口发送到另一个窗口,但从 C 到窗口不...
猜你喜欢
  • 1970-01-01
  • 2019-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-28
  • 1970-01-01
相关资源
最近更新 更多