Yakın zamanda bu soruna rastladım (başka bir yolla: Vim uzak bir sunucuda çalışıyor ve ekranı unuttum), bir yol aramaya karar verdim.
İlk fikir, Vim tarafından kullanılan dosya tanımlayıcılarına bakmak ve yazmaya çalışmaktı. Vim'in fds'i, terminal emülatör tarafından açılan psedoterminali işaret ediyor, doğal olarak:
$ 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]
Ancak ilk birkaç denemem başarısız oldu:
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
^[
Ve ^M
elde edilmiştir CtrlVEscve CtrlVEntersırasıyla.
Hepsi terminalde gösterilen karakterlerle sonuçlandı (uzak oturuma uygulamadan önce bunu yerel olarak test ediyordum). Etrafta dolaşırken, bu SO postasını pseudoterminal cihaza yazmak için Python kullanarak buldum :
#!/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)
Ve etkileşimli bir python kabuğu üzerinde denemek çalıştı:
$ 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'
>>>
Bitti!