首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Linux C 語言實現自定義終端界面:將鍵盤輸入轉發給 Shell 並捕獲輸出

     編輯:程式設計綜合問答

需求本質

在 ncurses 繪製的 UI 中嵌入一個「真正的終端」區域:用戶輸入命令 → 轉發給 Shell → 捕獲輸出 → 顯示在 UI 區域。

核心技術:偽終端

普通管道 popen("ls") 無法支援交互式命令(如 vim、top、Tab 補全)。必須使用 PTY (Pseudo-Terminal),它模擬一個真實終端設備,擁有主從兩端:

  • Master 端:你的程序持有,讀寫數據
  • Slave 端:掛載 Shell(/bin/bash),以為自己在真終端

關鍵 API 流程

#include 
#include 
#include 

int master_fd, slave_fd;
pid_t child_pid;

// 1. 打開 PTY 對
if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) {
    perror("openpty");
    exit(1);
}

// 2. Fork 子進程運行 Shell
child_pid = forkpty(&master_fd, NULL, NULL, NULL);
if (child_pid == 0) {
    // 子進程:執行 Shell
    execl("/bin/bash", "bash", "-i", NULL); // -i 交互模式
    _exit(1);
}

// 3. 父進程:設置非阻塞,接入事件循環
fcntl(master_fd, F_SETFL, O_NONBLOCK);

// 4. ncurses 主循環中
while (running) {
    // 處理鍵盤輸入
    int ch = getch();
    if (ch != ERR) write(master_fd, &ch, 1);

    // 讀取 Shell 輸出
    char buf[1024];
    int n = read(master_fd, buf, sizeof(buf));
    if (n > 0) {
        // 將 buf 解析為 ANSI 轉義序列,渲染到 ncurses 窗口
        render_terminal_output(buf, n);
    }
    // ... 其他 UI 邏輯
}

難點與解決方案

難點方案
ANSI 轉義序列解析使用 libvterm 或 libtsm 庫,將字節流轉為網格字符+屬性
窗口大小同步ncurses SIGWINCH 處理器中 ioctl(master_fd, TIOCSWINSZ, &winsize)
信號傳遞父進程捕獲 SIGINT/SIGTSTP 等,kill(child_pid, sig) 轉發
UTF-8 寬字符ncursesw (libncursesw) + 設置 locale setlocale(LC_ALL, "")

現成輪子推薦

  • libvterm:輕量級終端模擬器核心,Neovim、kitty 終端均在用
  • notcurses:現代 C 終端 UI 庫,內建圖片/視頻渲染,支援 PTY
  • xterm.js (JS) + WebSocket + 後端 PTY:若可接受 Web 界面,開發效率最高

純 C 手寫 PTY 解析器工作量極大,強烈建議直接集成 libvterm 或改用 Web 技術棧。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved