2017-04-07 30 views
0

假設我有一個在curses屏幕上執行一些工作的ncurses程序,並最終打印出stdout。調用該程序c.c,編譯爲a.out如何使ncurses程序與其他linux utils一起工作?

我希望先火起來的ncurses,一些動作之後,a.out退出並打印c.cstdout,這是閱讀cat,因而文件c.c的打印內容。

#include <stdio.h> 
#include <ncurses.h> 

int main() { 
    initscr(); 
    noecho(); 
    cbreak(); 
    printw("hello world"); 
    refresh(); 
    getch(); 
    endwin(); 
    fprintf(stdout, "c.c"); 
    return 0; 
} 

我也希望./a.out | xargs vimls | ./a.out | xargs less工作。

但是,當我輸入./a.out | xargs vim,hello world從來沒有出現。該命令似乎沒有按順序執行,vim不打開c.c

使ncurses程序與其他linux utils一起工作的正確方法是什麼?

回答

2

管道使用標準輸出(標準輸出)和標準輸入(標準輸入)。

最簡單的方式 - 而不是使用initscr,初始化輸出使用標準輸出,使用newterm,它允許您選擇的文件描述符,例如,

newterm(NULL, stderr, stdin); 

而非

initscr(); 

,它是(幾乎)相同

newterm(NULL, stdout, stdin); 

順便說一下,當您包含<ncurses.h>(或<curses.h>)時,不需要包含<stdio.h>

如果您想在管道的中間中使用您的程序,那會更復雜:您將不得不排空標準輸入並打開實際的終端設備。但那是另一個問題(並已被回答)。

延伸閱讀:

1

ncurses通過寫一堆ansi逃脫到標準輸出,終端將解釋。您可以運行./a.out > file,然後檢查該文件以查看您正在寫什麼實際上是。爲什麼節目都搞不清楚這將是顯而易見:

$ cat -vE file 
^[(B^[)0^[[?1049h^[[1;24r^[[m^O^[[4l^[[H^[[Jhello world^[[24;1H^[[?1049l^M^[[?1l^[>c.c 

這樣做是爲了跳過所有圖形/文本UI部件時,檢測到stdout不是終端,即它是由一個程序所消耗的正確方法而不是用戶:

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

int main() { 
    if(isatty(1)) { 
    // Output is a terminal. Show stuff to the user. 
    initscr(); 
    noecho(); 
    cbreak(); 
    printw("hello world"); 
    refresh(); 
    getch(); 
    endwin(); 
    } else { 
    // Output is consumed by a program. 
    // Skip UI. 
    } 
    fprintf(stdout, "c.c"); 
    return 0; 
} 

這是規範的Unix行爲。

如果您不想強制顯示您的用戶界面,無論如何,您可以draw your UI on stderr

+0

非常感謝你 – delta

+1

[newterm](http://man7.org/linux/man-pages/man3/curs_initscr.3x.html! )是通常的解決方案。 – rici

相關問題