我有一个 python dockerized 服务,它使用 PSL 创建 TTY 界面
pty
。
import os, pty
server, device = pty.openpty()
tty_name = os.ttyname(device)
我可以看到在容器内创建的这个界面
/dev/pts/0
:
ls -l /dev/pts
total 0
crw--w---- 1 aqlog tty 136, 0 Apr 28 14:50 0
现在我想将它公开(我猜是通过卷)到主机,以便外部服务使用
serial
: 连接它
import serial
ser = serial.Serial("/dev/tty_host")
我不能简单地映射一个体积:
volumes:
- "/dev/tty_host:/dev/pts/0"
因为该文件不存在,所以它是在容器运行时创建的映像构建。
我尝试使用触摸在图像构建时创建它,但由于权限错误而失败:
RUN su -c "touch /dev/pts/0"
所以我的问题是:是否可以向 docker 主机公开在容器内创建的串行接口?如果是这样,我该怎么办?
ls -l /dev/pts total 0 crw--w---- 1 aqlog tty 136, 0 Apr 28 14:50 0 ^^^^^^
与内核的通信是使用具有正确主次编号的字符特殊文件完成的。只有主编号和次编号相关,文件可以在任何地方创建。
在一个终端上我可以运行:
$ docker run -ti --rm python python -c 'import os, pty, time; a = pty.openpty(); print(os.ttyname(a[1])); print(os.fstat(a[1])); time.sleep(100000)'
/dev/pts/1
os.stat_result(st_mode=8592, st_ino=4, st_dev=139, st_nlink=1, st_uid=0, st_gid=5, st_size=0, st_atime=1714336460, st_mtime=1714336460, st_ctime=1714336460)
在另一个终端上在主机上然后我可以创建一个包含 139 主设备号和 0 次设备号的特殊设备文件。
mknod /tmp/mypts c 139 0
之后,
/tmp/mypts
可用于与管理pts设备的内核驱动程序进行通信,该驱动程序又将与容器内的进程进行通信。