惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
博客园_首页
U
Unit 42
Apple Machine Learning Research
Apple Machine Learning Research
云风的 BLOG
云风的 BLOG
MongoDB | Blog
MongoDB | Blog
美团技术团队
H
Help Net Security
G
Google Developers Blog
B
Blog RSS Feed
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
aimingoo的专栏
aimingoo的专栏
Google DeepMind News
Google DeepMind News
J
Java Code Geeks
M
MIT News - Artificial intelligence
腾讯CDC
IT之家
IT之家
Vercel News
Vercel News
C
Check Point Blog
博客园 - 三生石上(FineUI控件)
Last Week in AI
Last Week in AI
I
InfoQ
博客园 - 司徒正美
A
About on SuperTechFans

依云's Blog

Wayfire支持不缩放Xwayland啦 - 依云's Blog 使用wayvnc远程访问无头Wayfire会话 - 依云's Blog pacfiles: 高速的 pacman -F 替代品 用 Android 手机当电脑的话筒 - 依云's Blog 使用 ffmpeg 对音频文件进行响度归一化 - 依云's Blog 使用 nftables 屏蔽大量 IP - 依云's Blog YubiKey 初体验 - 依云's Blog fcitx5 码表同步方案 - 依云's Blog 我正在使用的火狐扩展(2024年版) - 依云's Blog 使用 PipeWire 实现自动应用均衡器 如果你发现你的 OOM Killer 在乱杀进程 使用 atuin 管理 shell 命令历史 btrfs 元数据满了怎么办 btrfs 翻车记 在 nspawn 里运行 docker Linux 上的字体配置与故障排除 新的 PaddleOCR 部署方案 使用 EasyEffects 调整 Bose 音箱的体验 让离线软件真正离线 我所讨厌的网页行为 tmux 状态栏优化 Google Chrome 中的字体设置 从 getmail6 到 offlineimap 微信消息通知的困扰 Qt 的字体渲染问题 Wayfire 迁移进展(四):不那么 high 的 DPI Wayfire 迁移进展(二):Xwayland HiDPI 以及 waybar Wayfire 迁移进展 不同情况下的图形效果 Wayland 初体验
rpysh——Windows Python 命令行也要 readline!
依云 · 2012-06-11 · via 依云's Blog

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,但是实际上没什么用,因为收到消息时之前的操作肯定已经执行完了