我如何獲得這個 pty,我可以用它做什麼?

我如何獲得這個 pty,我可以用它做什麼?

似乎一個簡單的 shell 重定向就為/dev/ptmx我提供了一個新的偽終端。

$ ls /dev/pts; ls /dev/pts </dev/ptmx
0  1  2  ptmx
0  1  2  3  ptmx

一旦擁有 fd 聲明的進程/dev/ptmx退出,它就會消失,但保留它很簡單:

$ PS1='<$(ls -1 "$@" /dev/pts/*|uniq -u)> $ ' \
  exec 3<>/dev/ptmx "$0" -si -- /dev/pts/*
</dev/pts/3> $ ls /dev/pts; exec 3>&-
0  1  2  3  ptmx
<> $ ls /dev/pts; exec 3<>/dev/ptmx
0  1  2  ptmx
</dev/pts/3> $ exit

所以看起來簡單的open()on/dev/ptmx就足以獲得一個偽終端。我想這會讓外殼 -(或其執行重定向的程序)- 公司主方的所有者。

但是我如何分配從屬端 - 或者我分配從屬端?如果可以的話——我能用它做什麼?我可以用 影響它的讀/寫/刷新時間嗎stty?在引用時,從屬端進程會連結到我的新 pty/dev/tty嗎?

答案1

因此,正如 @muru 在評論中指出的那樣,似乎沒有一種簡單的方法可以僅使用 shell 來連接為您創建的 pty。除了部分之外,我全部都做到了unlockpt()。根據我讀到的東西這裡核心中可能有一些編譯時選項用於停用新建立的 pty 鎖定,但我不想這樣做。所以,我做了別的事情。

我其實不需要grantpt()。根據描述發現這裡它所做的只是更改設備文件的 UID/GID /dev/pts/[num]。但據報道,man mount有更簡單的方法來處理這個問題。以下是一些devpts安裝選項:

  • uid=valuegid=value
    • 這會將新建立的 PTY 的擁有者或群組設定為指定的值。當沒有指定任何內容時,它們將被設定為創建進程的UID和GID。例如,如果有一個 終端 GID 5 的群組,gid=5則將導致新建立的 PTY 屬於終端團體。

預設情況下,我的系統就已經是這種情況了。但讀完之後,我意識到我最終可能想做出改變。下一節寫道:

  • ptmxmode=value
    • 設定檔案系統中新 ptmx 設備節點的模式devpts
    • 由於支援多個實例devpts(請參閱上面的選項),每個實例在檔案系統newinstance的根目錄中都有一個私有 ptmx 節點devpts(通常/dev/pts/ptmx
    • 為了相容於舊版的內核,新的 ptmx 節點的預設模式是0000. ptmxmode=value 為 ptmx 節點指定更有用的模式,並且在newinstance指定該選項時強烈建議使用。

雖然不這樣做也可以工作,但我喜歡這個想法並將其設置0640內核文件。順便說一下,內核文件連結詳細介紹了newinstance掛載選項 - 這非常酷,基本上使您能夠在每次掛載時獲得一組單獨的名稱空間 pty /dev/ptmx

無論如何,所以別的東西大部分為:

mount -o remount,newinstance,gid=5,ptmxmode=0640 /dev/pts
mount --bind /dev/pts/ptmx /dev/ptmx

....正如內核文件所建議的那樣 - 請參閱有關原因的連結。我還透過向我的/etc/fstab.

和...

<<\C cc -xc - -o pts
#include <stdio.h>
int main(int argc, char *argv[]) {
        if(unlockpt(0)) return 2;
        char *ptsname(int fd);
        printf("%s\n",ptsname(0));
        return argc - 1;
}
C

它只是編譯一個微小的 C 程序,嘗試調用unlockpt()其標準輸入,如果成功,則將新創建和解鎖的 pty 的名稱打印到,否則stdout默默返回 2。

一旦完成,我就可以創建自己的篩選的流程如下:

exec 3<>/dev/ptmx

....在目前 shell 中取得主端 fd 然後...

(setsid -c "$0" -i 2>&1|tee log) <>"$(./pts <&3)" 3>&- >&0 &

這會在後台偽終端機的另一端執行一個互動式 shell。它將把列印的任何內容解釋>&3為用戶輸入。

mikeserv@localhost$ echo echo hey >&3
mikeserv@localhost$ cat log
$ hey
$
mikeserv@localhost$ echo echo hey >&3
mikeserv@localhost$ cat log
$ hey
$ hey
$ 

這基本上為我提供了一個後台、日誌、互動式解釋器(或者我可能想在這些上運行的其他任何東西)alascreen沒有那麼多開銷,並且在我選擇的任何文件描述符上。

我目前 shell 擁有的主端 fd 是服務從端輸入的唯一方法,只能由我目前 shell 程序寫入(及其子項)。我可以透過寫入與另一端進行通信>&3,並且可以根據需要從同一文件或日誌文件中讀取。

畢竟stty在終端機上確實有效:

mikeserv@localhost$ echo stty -a ">$(tty)" >&3
speed 38400 baud; rows 0; columns 0; line = 0;                                      
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>;
swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W;
lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc
-ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl
echoke

相關內容