このptyをどのように入手し、どうすればよいですか?

このptyをどのように入手し、どうすればよいですか?

単純なシェルリダイレクトが/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()です/dev/ptmx。私の考えでは、これは殻を作ると思います -(またはリダイレクトを実行するプロセス)- 本会社のオーナーです。

しかし、スレーブ側をどのように割り当てますか?できるスレーブ側を割り当てますか?それでは - それで何ができますか?読み取り/書き込み/更新時間に影響を与える可能性がありますかstty?参照すると、スレーブ側のプロセスは私の新しいptyに接続されますか/dev/tty

答え1

したがって、@muruがコメントで指摘したように、シェルだけを使用して生成されたptyに接続する簡単な方法はないようです。私はそれの一部を除いてすべてをしましたunlockpt()。私が読んだ内容に基づいてここ新しく作成されたptyのロックを無効にするコンパイル時オプションがカーネルにあるかもしれませんが、私はそうしたくありません。それで私は別のことをしました。

必ずしも必要はありませんgrantpt()。説明に従って見つかりましたここそれがすることは、デバイスファイルのUID / GIDを変更することだけです/dev/pts/[num]。しかし、man mountこの問題を解決するより簡単な方法があることが知られています。以下はいくつかのdevptsインストールオプションです。

  • uid=valueそしてgid=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()stdin呼び出しを試み、成功すると新しく作成され、ロック解除されたptyの名前を印刷し、そうでなければstdout自動的に2を返します。

完了したら、自分だけのものを作ることができます。ろ過プロセスは次のとおりです。

exec 3<>/dev/ptmx

...現在のシェルからデフォルトの側面fdをインポートしてから...

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

これは、バックグラウンド擬似端末の反対側で対話型シェルを実行します。印刷されたすべての内容を>&3ユーザー入力として解釈します。

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

これは基本的にバックエンド、ロギング、インタラクティブな通訳を提供します。(または私が実行したい他のもの)alaはscreenオーバーヘッドが多く、私が選択したすべてのファイル記述子で動作します。

現在のシェルが所有するマスターfdは、スレーブ入力を処理する唯一の方法であり、現在のシェルプロセスでのみ書き込み可能です。(そしてその子)。書き込みは相手と通信し>&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

関連情報