如何用反引号修复initscr bug?

时间:2015-12-03 17:55:14

标签: c linux unix ncurses

我对函数initscr()有一个很大的问题。

#include <ncurses.h>
#include <stdlib.h>
#include <unistd.h>

int     main(int ac, char **av)
{
 WINDOW *win;

 initscr();
 printw("lol");
 getch();
 refresh();
 endwin();
 return (0);
}

当我编译此代码并执行./a.out时,它没关系,但是当我这样做时

lol=`./a.out`

initscr没有出现。我在文章中读到函数newterm,但它是一样的。

3 个答案:

答案 0 :(得分:1)

我找到了解决方案。我使用newtermstderr作为输出文件描述符,它可以工作。

int         main(int ac, char **av)
{
  SCREEN    *win;

  win = newterm(NULL, stderr, stdin);
  printw("lol");
  getch();
  refresh();
  endwin();
  return (0);
}

答案 1 :(得分:1)

您可以使用script实用程序捕获终端上任何命令的输出,该实用程序通常默认安装。它将程序的所有输出保存到名为typescript的文件中,并且不会干扰程序。使用Linux,您可以按如下方式运行它:

script -c ./a.out

(对于其他系统,例如OSX,您可能没有-c选项:script没有POSIX标准。

但是,您可能会发现结果出乎意料,因为它们会与转义序列混合在一起。例如,在TERM设置为vt100的情况下运行您的程序,并使用unmap以可打印的形式显示非打印字符,我看到了:

Script started on Thu 03 Dec 2015 08:09:15 PM EST
\n
\E(B
\E)0
\E[1;40r
\E[m^O
\E[?7h
\E[H
\E[Jlol\r
\E[40;1H\r
\E[?1l
\E>
\nScript done on Thu 03 Dec 2015 08:09:16 PM EST
\n

与使用标准输出进行屏幕更新时,某些程序(例如dialog)故意在标准错误上写入消息,而不是尝试将消息与转义序列分开。或者(使用newterm)你可以反转它,使获取信息变得简单。

以下是使用该方法的修订程序:

#include <ncurses.h>
#include <stdlib.h>
#include <unistd.h>

static void
show(const char *msg)
{
    printw("%s", msg);
    if (!isatty(fileno(stdout)))
    puts(msg);
}

int
main(int ac, char **av)
{
    newterm(NULL, stderr, stdin);
    show("lol");
    getch();
    endwin();
    return (0);
}

修订后的计划:

  • 使用函数show写入其消息,该函数写入屏幕并可选择写入消息
  • 它使用isatty检查标准输出是否不是tty,即您正在重定向程序的输出。没有检查,两个(输出和错误)都会写入屏幕,弄乱它。
  • 完成了一些小的清理工作:删除一个未使用的变量,并对refresh进行不必要的调用(因为getch已经这样做了。)

此命令

lol=`./a.out`

将对lol执行请求的分配,而不会干扰屏幕更新。

答案 2 :(得分:0)

如果要将a.out的输出分配给shell变量并在终端窗口中查看输出,请使用teeHere为例)。 tee(shell程序)有效地允许您复制进程的输出并将其一次发送到两个位置(在您的情况下,shell变量和终端)。

示例(基于上述链接中给出的解决方案):

exec 5>&1
lol=$(./a.out | tee > (cat - >&5))