เมื่อเร็ว ๆ นี้พบปัญหานี้ (ผ่านวิธีอื่น: เรียกใช้บนเซิร์ฟเวอร์ระยะไกลและฉันลืมหน้าจอ) ฉันตัดสินใจที่จะหาวิธี
แนวคิดแรกคือค้นหาตัวอธิบายไฟล์ที่ Vim ใช้และลองเขียนลงไป fds ของ Vim ชี้ไปที่ psedoterminal ที่เปิดโดย terminal emulator โดยธรรมชาติเพียงพอ:
$ ls -l /proc/$(pgrep -n vim)/fd/
total 0
lrwx------ 1 muru muru 64 Nov 17 01:25 0 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 1 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 2 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 3 -> socket:[99564312]
อย่างไรก็ตามความพยายามครั้งแรกของฉันล้มเหลว:
echo '^[:wq^M' > /proc/$(pgrep -n vim)/fd/0
echo ':wq^M' > /proc/$(pgrep -n vim)/fd/0
echo ':wq^M' > /proc/$(pgrep -n vim)/fd/0
echo '^C' > /proc/$(pgrep -n vim)/fd/0
printf "%s" '^[:wqa!^M' > /proc/$(pgrep -n vim)/fd/0
^[
และ^M
ได้รับโดยCtrlVEscและCtrlVEnterตามลำดับ
พวกเขาทั้งหมดส่งผลให้ตัวละครปรากฏขึ้นที่สถานี (ฉันกำลังทดสอบเรื่องนี้ในพื้นที่ก่อนที่จะนำไปใช้กับเซสชันระยะไกล) ฉันพบโพสต์ SO นี้โดยใช้ Python เขียนไปยังอุปกรณ์ pseudoterminal:
#!/usr/bin/python
import sys,os,fcntl,termios
if len(sys.argv) != 3:
sys.stderr.write("usage: ttyexec.py tty command\n")
sys.exit(1)
fd = os.open("/dev/" + sys.argv[1], os.O_RDWR)
cmd=sys.argv[2]
for i in range(len(cmd)):
fcntl.ioctl(fd, termios.TIOCSTI, cmd[i])
fcntl.ioctl(fd, termios.TIOCSTI, '\n')
os.close(fd)
และลองใช้กับ python shell ที่ใช้การได้:
$ sudo python3
Python 3.5.0 (default, Sep 20 2015, 11:28:25)
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, fcntl, termios
>>> fd = os.open('/dev/pts/14', os.O_RDWR)
>>> a = '\033:wqa!\n'
>>> for i in a: fcntl.ioctl(fd, termios.TIOCSTI, i);
...
b'\x1b'
b':'
b'w'
b'q'
b'a'
b'!'
b'\n'
>>>
ทำ!