【问题标题】:Pseudo-terminal not printing output伪终端不打印输出
【发布时间】:2017-09-03 22:51:25
【问题描述】:

这是我的代码,旨在打开一个额外的 gnome 终端并在新打开的终端控制台中打印前 20 个斐波那契数:

#include <stdio.h>
#include "apue.h"

int Fibonacci(unsigned int n);

int main() {
    char cmd[256];
    char str[40][256];
    char *name = tempnam(NULL, NULL);
    char *line = "\n";
    FILE *log;

    mkfifo(name, 0777);
    log = fopen(name, "w+");

    for (unsigned int i = 0; i < 20; i++) {
         sprintf(str[(2 * i)], "%s",line);
         fputs(str[(2 * i)], log);
         sprintf(str[(2 * i) + 1], "%u\n", Fibonacci(i));
         fputs(str[(2 * i) + 1], log);
         fflush(NULL);
    }
    if (fork() == 0) {
        sprintf(cmd, "gnome-terminal -e cat %s", name);
        system(cmd);       
        for (unsigned int j = 0; j < 40 ; j++) {    
            fgets(str[j], sizeof(cmd), log);            
        }
        exit(0);
    } else
    if (fork() < 0) {
        perror("fork () error");    
    }
}

int Fibonacci(unsigned int n) {
    if (n == 0) {
        return 0;
    } else
    if (n == 1) {
        return 1;
    } else
    if (n > 1) {
        return Fibonacci(n - 2) + Fibonacci(n - 1);
    }
}

当我编译它时,我收到以下警告消息:

-*- mode: compilation; default-directory: "/usr/lib/gcc/x86_64-linux-gnu/4.8.4/include/" -*-
Compilation started at Sun Sep  3 15:46:28

gcc  -o FIB0   Fibonacci.c
/tmp/ccobnJV9.o: In function `main':
Fibonacci.c:(.text+0x231f): warning: the use of `tempnam' is dangerous, better use `mkstemp'

Compilation finished at Sun Sep  3 15:46:28

当我从 gnome 终端命令行执行它时,新终端会弹出,但没有输出!如何修复此代码以使其正常工作?

当我使用时

 sprintf(cmd, "xterm -e cat %s", name);

而不是“gnome-terminal”,它可以正常工作。那么如何使用 GCC 在 gnome 终端之间进行通信呢?

【问题讨论】:

  • 与使用 tempnam 没有任何关系。
  • @immibis:好点子。当我在 sprintf() 函数中将“gnome-terminal”替换为“xterm”时,它会起作用。

标签: c gcc pty


【解决方案1】:

你的分叉机制有一个额外的问题:

if (fork() == 0) {
    /* do something in the child */
} else
if (fork() < 0) {   //<--- fork AGAIN!
    perror("fork () error");    
}

父进程被分叉了两次!

您应该存储 pid:

int pid = fork();
if (pid == 0) {
    /* do something in the child */
} else
if (pid < 0) {
    perror("fork () error");    
}

【讨论】:

  • 当我通过调用 fork() 实现您的更改时,发生的第一件事是主终端打印“fork() 错误:成功”,并在几乎 1 秒延迟后显示输出在新航站楼。而原始代码不会产生这样的错误消息,并且新终端会立即弹出所需的输出。嗯……
【解决方案2】:

试试

sprintf(cmd, "gnome-terminal -e \"cat %s\"", name);

gnone-terminal 的 man 请求 -e 之后的字符串。

【讨论】:

  • 现在完美工作。谢谢!
【解决方案3】:

在命令行中试试。

如果我跑

echo hi > ~/temp
gnome-terminal -e cat ~/temp

然后我得到一个运行 cat 的终端(最初是空白的,直到我输入一些内容并按 Enter 键)

如果我跑

xterm -e cat ~/temp

然后我会弹出一个 xterm,打印“hi”并很快关闭。

所以看来gnome-terminal -e cat /some/path 没有运行cat /some/path,而只是运行cat

如果你想在 gnome-terminal 中运行cat /some/path,那么你必须使用命令:

gnome-terminal -e "cat /some/path"

注意多余的引号。

【讨论】:

    【解决方案4】:

    按照 immibis 的建议使用引号,或者使用 -x 而不是 -e。有关详细信息,请参阅gnome-terminal 的手册页。

    【讨论】:

      猜你喜欢
      • 2020-02-24
      • 1970-01-01
      • 1970-01-01
      • 2014-11-29
      • 1970-01-01
      • 2012-10-31
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      相关资源
      最近更新 更多