2017-04-07 70 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

相关问题