Suppose I have a ncurses program which does some job on curses screen, and finally print something to stdout
. Call this program c.c
, compiled to a.out
.
I expect cat $(./a.out)
first fire up ncurses, after some action, a.out
quits and print c.c
to stdout
, which is read by cat
, and thus print content of file 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;
}
I also expect ./a.out | xargs vim
, ls | ./a.out | xargs less
to work.
But when I type ./a.out | xargs vim
, hello world
never shows up. The command seems not executed in order, vim does not open c.c
.
What is the correct way to make a ncurses program to work with other linux utils?
Pipes use the standard output (stdout) and standard input (stdin).
The simplest way - rather than using initscr
, which initializes the output to use the standard output, use newterm
, which allows you to choose the file descriptors, e.g.,
newterm(NULL, stderr, stdin);
rather than
initscr();
which is (almost) the same as
newterm(NULL, stdout, stdin);
By the way, when you include <ncurses.h>
(or <curses.h>
), there is no need to include <stdio.h>
.
If you wanted to use your program in the middle of a pipe, that is more complicated: you would have to drain the standard input and open the actual terminal device. But that's another question (and has already been answered).
Further reading: