似乎一个简单的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
就足以获得伪终端。我猜想这将使shell (或它进行重定向的过程)成为pty的主端的所有者。
但是,我该如何分配从站侧呢?还是可以分配从站侧呢?如果可以的话-我该怎么办?我可以影响它的读/写/刷新时间stty
吗?参考时,从属方进程会链接到我的新pty/dev/tty
吗?
因此,正如@muru在注释中指出的那样,似乎没有一种简单的方法可以将为您创建的pty与shell进行接口。除unlockpt()
部分内容外,我全部进行了处理。根据我在此处阅读的内容,内核中可能有一些编译时选项用于禁用新创建的pty锁定,但是我不想这样做。所以,我做了其他事情。
我grantpt()
实际上并不需要。根据此处找到的描述,它所做的只是更改/dev/pts/[num]
设备文件的UID / GID 。但是据介绍,man mount
有更简单的方法可以解决该问题。以下是一些devpts
安装选项:
uid=value
和 gid=value
gid=5
则将导致新创建的PTY属于tty组。默认情况下,在我的系统上已经是这种情况。但是阅读完之后,我意识到我可能还是想做出改变。下一节的内容为:
ptmxmode=value
devpts
文件系统中为新的ptmx设备节点设置模式。devpts
(请参见newinstance
上面的选项),每个实例在devpts
文件系统根目录(通常是/dev/pts/ptmx
)中都有一个私有ptmx节点。0000
。ptmxmode=value
为ptmx节点指定一种更有用的模式,强烈建议在newinstance
指定该选项时使用。如果不这样做,它可能会起作用,但我很喜欢这个主意,并将其设置0640
为内核文档中推荐的值。顺便说一句,内核doc链接详细说明了newinstance
mount选项-这很酷,基本上可以使您在每次/dev/ptmx
安装时获得一个单独的以名称分隔的pty组。
无论如何,所以其他的东西主要是:
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
...以便在当前shell中获得主端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
而没有那么多的开销和我选择的任何文件描述符。
我当前的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
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句