NCURSES SW 在 lxterminal 中執行,但不在本機 Linux 終端中執行
ncurses
我使用該庫編寫了一個“複雜”的 C 程序。它“正確地”在一個lxterminal
或gnome-terminal
會話中執行;但不會在沒有啟動 X 的“本機 Linux 終端”會話中執行(在沒有 X的**情況下重新啟動 PC 或使用Ctrl
-終端)。Alt``F3
問題是在“本機 Linux 會話”中,程序不顯示任何視窗,它只顯示第三個生成視窗中列印的文本之一。
- 我看到在 gnome-terminal
TERM
環境變數設置為xterm-256color
. 相比之下,本機 Linux 終端已TERM
設置為linux
.- 然後我
TERM
在本機 Linux 終端中使用:export TERM=xterm-256color
當我設置
TERM
為xterm-256color
程序執行得更好並顯示一個可用的界面,但所有構造框的字元都被其他字元替換時,垂直線字元被字元替換x
。
- 但我認為
xterm
是針對 X 終端部分,然後我嘗試了ansi
:export TERM=ansi
使用最後一個設置,程序幾乎不顯示任何內容,就像在本機設置的情況下一樣。
- 使用
vt100
:export TERM=vt100
程序執行得更好,但以黑白顯示。
與 ncurses 庫一起發布的範例也會發生相同的行為。
你有什麼解釋嗎?
如何以可以正確啟動 ncurses 程序的方式設置終端功能?
有可能我沒有在程式碼中設置與終端(或與 ncurses 相關)相關的內容嗎?
例子
#include <ncurses.h> static void initGeneralScreen(void); int main() { WINDOW * deskW, * msgW, * otherW; initGeneralScreen(); deskW = newwin(21,80,0,0); wbkgd(deskW, COLOR_PAIR(3)); box(deskW, 0, 0 ); // sets default borders for the window wrefresh( deskW ); // update the terminal screen msgW = newwin(3, 80, 21, 0); wbkgd(msgW, COLOR_PAIR(1)); box(msgW, 0, 0 ); // sets default borders for the window wrefresh(msgW ); // update the terminal screen otherW = newwin(1,78,0,1); wbkgd(otherW, COLOR_PAIR(1)); wrefresh(otherW ); // update the terminal screen mvwprintw(msgW,1,1,"Test ... <Hit a key to exit>"); wrefresh(msgW ); // update the terminal screen mvwprintw(otherW,0,0,"Test1"); wrefresh(otherW ); // update the terminal screen wgetch(deskW); delwin( otherW ); delwin( msgW ); delwin( deskW ); endwin(); return 0; } void initGeneralScreen(void) { initscr(); // initialize Ncurses noecho(); // disable echoing of characters on the screen raw(); // keypad(stdscr,TRUE); start_color(); init_pair(1,COLOR_YELLOW | 8, COLOR_BLUE); init_pair(2,COLOR_YELLOW, COLOR_BLUE); init_pair(3,COLOR_WHITE | 8, COLOR_BLACK | 8); }
筆記:
- 核心
Linux 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
libncurses.so.5.9
我變了
init_pair(1,COLOR_YELLOW | 8, COLOR_BLUE); init_pair(2,COLOR_YELLOW, COLOR_BLUE); init_pair(3,COLOR_WHITE | 8, COLOR_BLACK | 8);
至
init_pair(1,COLOR_YELLOW, COLOR_BLUE); init_pair(2,COLOR_YELLOW, COLOR_BLUE); init_pair(3,COLOR_WHITE, COLOR_BLACK);
程序開始按預期工作。
出現問題是因為您使用Linux 虛擬終端不支持的背景顏色(按
wbkgd
功能) 。它僅支持 8 種背景顏色和 8 種前景顏色 -關於 ncurses 顏色。看:
printf("COLOR_YELLOW\t\t%d\n", COLOR_YELLOW); printf("COLOR_BLUE\t\t%d\n", COLOR_BLUE); printf("COLOR_BLACK\t\t%d\n", COLOR_BLACK); printf("COLOR_WHITE\t\t%d\n", COLOR_WHITE); puts(""); printf("COLOR_YELLOW | 8\t%d\n", COLOR_YELLOW | 8); printf("COLOR_BLACK | 8\t\t%d\n", COLOR_BLACK | 8); printf("COLOR_WHITE | 8\t\t%d\n", COLOR_WHITE | 8);
輸出
COLOR_YELLOW 3 COLOR_BLUE 4 COLOR_BLACK 0 COLOR_WHITE 7 COLOR_YELLOW | 8 11 // not allowed for background COLOR_BLACK | 8 8 // not allowed for background COLOR_WHITE | 8 15 // not allowed for background
編輯
1.
根據init_pair 簽名:
int init_pair(short pair, short f, short b);
第二個參數用於前景,第三個用於背景,因此在您的範例中,顏色對中唯一的第三個參數
3
應從簡單更改COLOR_BLACK | 8
為簡單COLOR_BLACK
。因此,這在 Linux 控制台中是合法的:
init_pair(1,COLOR_YELLOW | 8, COLOR_BLUE); init_pair(2,COLOR_YELLOW, COLOR_BLUE); init_pair(3,COLOR_WHITE | 8, COLOR_BLACK);
TERM=xterm-256color
這是回答為什麼在控制台中設置時看不到太多顏色變化的原因。因為只有COLOR_BLACK | 8
不支持,其他都很好。並且COLOR_BLACK | 8
沒有按預期工作 - 表格的主體是純黑色的,不像gnome-terminal,它是灰色的。因此,正如您在評論中所寫,顏色並不完全正確。2. 為什麼在 gnome-terminal 中的行為不同?
因為gnome-terminal和Linux 控制台是兩個終端仿真器,它們使用不同的轉義序列集。將它們視為來自不同供應商的兩個不同硬體終端。
- xterm 是 X Window 系統的標準終端仿真器。
- gnome-terminal是
xterm
兼容的終端仿真器。- Linux 控制台是駐留在核心中的VT102仿真器。不是嚴格的,例如VT102沒有顏色。
這就是為什麼
ncurses
需要庫 - 編寫獨立於終端的應用程序。每個終端仿真器功能的集合都儲存在terminfo
數據庫中。Linux 控制台有自己的入口,還有gnome-terminal。ncurses
使用來自該數據庫的資訊來管理終端仿真器。您可以通過此命令比較條目:
infocmp -c linux xterm-256color
因此,當您在 Linux 控制台中將
TERM
變數 from更改為linux
to時,您會說使用一組外部轉義序列與終端進行通信,而不是真實的(正確的)。儘管如此,有些程式碼還是可以理解的,因為它們有相似之處,但不是全部。xterm-256color``ncurses
相關連結: