2016-11-04 55 views
-1

我已经写了一个基于libcurses的ascii ui,它在程序退出时将文本写入标准输出。为什么libncurses ui在捕获到Bash变量时不显示?

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

> ./test

...的UI显示。

但是,如果我尝试捕捉程序输出到猛砸变量,像这样......

> foo=$(./test)

...用户界面不显示,但是在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; 
} 

回答

1

很简单,因为重定向STD输出(>a=$(…))只是重定向标准输出 - ncurses的,在另一方面,直接交谈终端并显示字符,即从未是标准输出的一部分。

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

有没有办法让ui在试图捕获它的stdout到Bash变量时出现?

我不推荐。因为你在混合使用非交互式使用(获得标准输出)和交互式,并且最终不能很好地执行,但是:

您可以像其他任何C程序员一样结束ncurses会话并使用printf 。那么你实际上正在生产标准输出。

我宁愿只是添加一个选项,我的程序,需要一个文件,我写我的输出。然后,bash脚本可以在程序运行后打开该文件。

+0

你知道有什么办法可以实现我想要做的事情?即显示ui,然后立即自动将stdout捕获到Bash变量中?我对* nix和/或Bash没有足够的专业知识来思考如何做到这一点。 – StoneThrow

+0

“我宁愿只为我的程序添加一个选项,该选项将一个文件写入我的输出中,然后bash脚本可以在我的程序运行后打开该文件。” - 得到你。谢谢。 – StoneThrow

+0

你的答案大多不正确。 –

1

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

适应你的榜样,

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

,并看着$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' 
+0

你的答案大部分是正确的:)不,认真的说,ncurses默认使用附加到标准输出的* virtual term *,而不是标准输出 - 这可能是也可能不是相同的东西(也就是你捕获的控制字符),或者实际上是像控制终端设备的ioctl一样疯狂 –

相关问题