• rpysh——Windows Python 命令行也要 readline!


    rpysh 是为习惯 Linux 的 Pythoners 在不得不处理 Windows 上的事务时写的远程 shell。

    源起

    前些天,我尝试了使用 Python 控制 Word。但我对 Windows 下的交互式 Python shell 很不满意。

    首先,我尝试的是 cmd.exe 那个黑窗口。太难用了!只有最基本的行编辑、在不知不觉中历史记录被窜改、复制粘贴极其麻烦。补全当然也是没有的。

    于是,尝试 IDLE。这家伙我选了「IDLE Classic Unix」,但是能工作的键并不多。比如我刚刚尝试的Ctrl-u就不管用。而Ctrl-p竟然是把光标向上移动,回车才会把那行的内容取到输入命令的那行。这样一来,想再次执行最后一条语句,需要视上条命令输出的行数按几下Ctrl-p。另外,鼠标在窗口内点击后光标会被移开。这样,我使用鼠标从其它窗口切回来时,还得再手动定位光标,极其不爽。至于补全么,太智能了,所以在我输入时不时会出现这种情况:

    乱七八糟的补全

    还有一个问题:我查资料、做笔记、写代码都在 Linux 上,虽然Ctrl-CCtrl-V在物理机和虚拟机间能够无缝操作,但比起选中+中键粘贴的 X 主选区还是麻烦多了!

    没办法,我只好重拾很久以前的想法——写个程序,在 Linux 上操作,在 Windows 上执行!

    ——等等!这和 ssh 差不多吗?或者 telnet?

    ——不不,Cygwin 的 ssh 跑不了 Windows 控制台程序,而且,不还是没 readline 支持么?

    实现

    毫无疑问是网络通信了。距离上一次不成功的尝试已经过去很久了,我不仅更加了解了code模块的能力,也知道 Python 命令行补全是怎么回事了。也就是说,Windows 版的 Python 是有补全的接口的,只是没有 readline 的等价物来调用。跑在 Windows 上的服务端要完成以下操作:

    1. 重写相关方法,把用户数据由标准输入改到从客户端读取
    2. 标准输出重定向到网络 socket
    3. 收到客户端的补全请求后,使用rlcompleter模块获取补全结果,再回送给客户端

    对于第一点,实际上取代code.InteractiveConsole实例的raw_input方法就行。它和内建的input()函数具有相同的输入和输出形式,也就是会接收命令提示符。将这个直接发给客户端好了。

    第二点很简单,直接socket.makefile然后把sys.stdout指过去。

    第三点,为了简单起见,我另开了个线程和 socket,专门用于补全。需要传递的参数和返回值全部 pickle 了扔给对方就是了。

    写完这些我才发现,其实我的raw_input方法和补全函数具有相似的执行逻辑:发送参数到网络,再从网络获取执行结果——也就是远程过程调用呵。

    使用方法

    rpyshd.py可选一个参数作为端口号,为方便起见,提供默认值8980。也是为了方便双击执行起见,我添加了.py后缀。

    rpyshc相当于telnet命令了,直接接主机地址和端口号两个参数即可。

    缺陷

    • 从标准输入读数据时在服务端
    • 偶尔提示符出现不及时
    • 虽然我实现了Ctrl-C,但是实际上没什么用,因为收到消息时之前的操作肯定已经执行完了
  • 相关阅读:
    java坏境内存不够用 大量占用swap 临时加swap
    磁盘分区
    简述raid0,raid1,raid5,raid10 的工作原理及特点
    给用户提权
    用户的环境变量被删除了
    定时任务
    linux权限
    kafka部署
    数据仓库
    kylin
  • 原文地址:https://www.cnblogs.com/shihao/p/2701107.html
Copyright © 2020-2023  润新知