2016-11-04 52 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一樣瘋狂 –

相關問題