[英]how to make ncurses program working with other linux utils?
假設我有一個ncurses程序,該程序在curses屏幕上完成一些工作,最后將一些內容打印到stdout
。 將此程序cc
編譯為a.out
。
我希望cat $(./a.out)
首先啟動ncurses,在執行某些操作后, a.out
退出並將cc
打印到stdout
,該目錄由cat
讀取,從而打印文件cc
內容。
#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 vim
./a.out | xargs vim
ls | ./a.out | xargs less
ls | ./a.out | xargs less
ls | ./a.out | xargs less
工作。
但是當我輸入./a.out | xargs vim
./a.out | xargs vim
, hello world
永遠不會出現。 該命令似乎未按順序執行,vim無法打開cc
。
使ncurses程序與其他linux utils配合使用的正確方法是什么?
管道使用標准輸出(stdout)和標准輸入(stdin)。
最簡單的方法-使用initscr
,而不是使用initscr
初始化輸出以使用標准輸出 ,而是使用newterm
,它允許您選擇文件描述符,例如,
newterm(NULL, stderr, stdin);
而不是
initscr();
(幾乎)與
newterm(NULL, stdout, stdin);
順便說一句,當您包含<ncurses.h>
(或<curses.h>
)時,無需包含<stdio.h>
。
如果要在管道中間使用程序,那將更加復雜:您必須排空標准輸入並打開實際的終端設備。 但這是另一個問題(並且已經得到回答)。
進一步閱讀:
ncurses
通過將一堆ansi轉義寫入stdout來工作,終端將對其進行解釋。 您可以運行./a.out > file
,然后檢查該文件以查看實際編寫的內容。 顯而易見為什么程序會被混淆:
$ cat -vE file
^[(B^[)0^[[?1049h^[[1;24r^[[m^O^[[4l^[[H^[[Jhello world^[[24;1H^[[?1049l^M^[[?1l^[>c.c
正確的方法是在檢測到stdout不是終端時跳過所有圖形/文本UI部分,即它是由程序而不是用戶使用的:
#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行為。
如果您想無論如何都強制顯示UI,則可以在stderr上繪制UI 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.