Shell

終端和外殼如何交換數據?

  • April 27, 2017

在 Linux 中,終端與 Shell 相關聯。終端將輸入發送到 Shell(例如:)pwd,Shell 將輸出發送回終端(例如:)/home/paul

此圖顯示了終端和 Shell 之間的關係(假設我使用的終端是gnome-terminal,而 Shell 是bash):

在此處輸入圖像描述

現在我想知道的是終端和外殼使用什麼機制來交換數據。這就是我認為發生的事情:

  • 執行時gnome-terminal,它會在目錄中創建一個代表串口的/dev/pts文件(假設文件名為/dev/pts/0)。
  • gnome-terminal然後將執行與其關聯的 Shell(例如bash:),並將 pts 文件名傳遞給它(例如,pts 文件名可以通過命令行參數傳遞)。
  • 現在兩者都gnome-terminal將從bash開始閱讀/dev/pts/0
  • gnome-terminal要向 發送數據時bash,它會將這些數據寫入/dev/pts/0,並bash從中讀取此數據/dev/pts/0
  • bash要向其發送數據時gnome-terminal,它會將這個數據寫入/dev/pts/0and gnome-terminal從中讀取這個數據/dev/pts/0

這張圖顯示了我剛剛解釋的內容:

在此處輸入圖像描述

我的理解正確嗎?


注意:如果我們使用虛擬終端(即當我們不使用 GUI 時),pts 文件當然可以是 tty 文件,但邏輯仍然是相同的。

你錯過了一個必要的部分。偽 tty 設備不像套接字那樣對稱。有主端和從端。中的文件/dev/pts代表從設備。

終端仿真器通過呼叫創建一個偽 tty openpty(或者對於您想要在新 tty 上執行新程序的常見情況,forkpty這是openpty額外的一些設置)。在較低級別,這涉及打開/dev/ptmx並執行一些魔術 ioctl。

通過呼叫openpty終端仿真器得到一對文件描述符,並且還可以得到/dev/ptsslave對應的文件名。主程序沒有單獨的名稱,因為從不需要子程序按名稱打開它。

主設備和從設備的行為確實有點像套接字的兩端:你在一端寫入的內容是從另一端讀取的。但是因為這是一個 tty,所以所有的 tty 模式都適用於通過的數據。

例如,如果您是終端仿真器,並且您收到按鍵的A按鍵,您應該寫入'a'主文件描述符。這直接相當於通過串列線從終端向電腦發送該字節。它將導致'a'從從站讀取(通過正在讀取它的任何程序 - 例如外殼)。

D如果您在按鍵按下時收到按鍵按下Ctrl,您應該將一個4字節 ( 'D' ^ 0x40) 寫入主文件描述符。(因為那是真正的終端線上路上發送的內容。)接下來發生的事情取決於 tty 模式。在原始模式下,讀取從 tty 的程序將看到一個4字節。在熟模式下,tty 將啟動“EOF 特殊鍵按下”行為。

在反方向,也有一些處理。當某些程序寫入從 tty 時,由於後處理'\n',您可能會"\r\n"在主文件描述符上收到。onlcr

歷史部分,無聊請跳過

很久以前,從設備的名稱為like /dev/ttyp0,每個設備都有一個對應的主設備,如/dev/ptyp0。它們不是動態創建的。終端仿真器可以對它們全部進行探測以找到目前未使用的一個,然後開始使用它。管理所有權和權限是一個問題。xterm是 setuid-root 只是為了它可以 chown 奴隸。

名為“UNIX98 ptys”的新方案通過神奇的 ioctl 處理設備創建和所有權,因此文件僅/dev/pts在使用時出現,並且歸執行創建它們的程序的使用者所有。

引用自:https://unix.stackexchange.com/questions/361745