捕获到Bash变量时为什么libncurses ui不显示?

时间:2016-11-04 07:49:23

标签: bash ncurses

我编写了一个基于libcurses的ascii ui,当程序退出时将文本写入stdout。

如果我单独执行程序,就像这样......

> ./test

... ui显示。

但是,如果我尝试将程序输出捕获到Bash变量,就像这样......

> foo=$(./test)

... ui不显示,但Bash变量捕获预期输出。

有谁知道为什么这种行为如此?有没有办法让ui在尝试将其stdout捕获到Bash变量时出现?

守则

#include <iostream>
#include <curses.h>
#include <unistd.h>

int main(int argc, char* argv[])
{
    WINDOW* pWindow = initscr();
    keypad(pWindow, TRUE);
    curs_set(0);
    nodelay(pWindow, FALSE);

    mvwprintw(pWindow, 5, 5, "hello, world!");
    mvwprintw(pWindow, 6, 5, "hello, fold!");
    mvwprintw(pWindow, 7, 5, "hello, toad!");

    for (int i = 0; i < 5; ++i)
    {
        mvwprintw(pWindow, 5 + i, 1, "==>");

        refresh();

        usleep(500000);

        mvwprintw(pWindow, 5 + i, 1, "   ");
        refresh();
    }

    endwin();

    std::cout << "bar" << std::endl;
}

2 个答案:

答案 0 :(得分:1)

仅仅因为重定向std输出(>a=$(…))只是重定向标准输出 - 另一方面,ncurses直接与终端对话并显示字符,这些字符从不是stdout的一部分

简短:它没有捕获输出,因为没有。相反,ncurses程序直接与底层终端通信。

  

有没有办法在尝试将stdout捕获到Bash变量时让ui显示出来?

我不推荐。因为你混合非交互式使用(获得标准输出)和交互式,并且最终不能真正顺利,但是:

你可以结束你的ncurses会话,就像任何其他C程序员一样使用printf。那么你实际上是在生成标准输出。

我更愿意在我的程序中添加一个选项,该选项包含我编写输出的文件。然后bash脚本可以在程序运行后打开该文件。

答案 1 :(得分:1)

使用initscr初始化curses时,它将使用标准输出进行显示。 (您可以使用newterm指定另一个输出)。因此,当您重定向程序的输出时,您将看不到用户界面。

调整您的示例,

#!/bin/bash
g++ -o test foo.c $(ncursesw6-config --cflags --libs)
foo=$(./test)
set >foo.log

并查看bash放入$foo的内容,我看到了用户界面中编写的预期控制字符,例如,

foo=$'\E[?1049h\E[1;40r\E(B\E[m\E[4l\E[?7h\E[?1h\E=\E[?25l\E[H\E[2J\E[6d ==> hello, world!\n\E[6Ghello, fold!\n\E[6Ghello, toad!\E[6;5H\r    \r\n ==>\r    \r\n ==>\r    \r\n ==>\r\E[J    \r\n ==>\r\E[J    \E[40;1H\E[?12l\E[?25h\E[?1049l\r\E[?1l\E>bar'