Python 如何获取终端实时输出

2020-02-06 19:14:06 +08:00
 oIMOo

各位好。

提问前,我已经 Google 了一圈,因为种种原因,我并没有找到答案。然后才来提问。

首先理想状态是这样的:

问题 (1): 同一个文件可以做到交互吗?

不能的话,就退而求其次,使用两个文件。

问题 ( 2 ): 我会基本的获取某命令输出。但由于上面获取输出时,A 并没有执行完成。 尝试了 subprocess.Popen 和 os.popen 都获取不到,也可能时我方法不对? 求如何获取?

附:A.py 文件实例:

x = input("Value x: ") 
print("x = ", x)

目的: B 要获取这个 “Value x: ”,并根据获取到的结果再传入指定的值,完成 input()。

感谢!


目前的辣鸡方法:

执行 A 并使用 tee 输出到 C,然后读 C 进行处理……

6523 次点击
所在节点    Python
29 条回复
wuwukai007
2020-02-06 19:19:30 +08:00
同一个文件可以吧,处理完后调用 os.system("clear")不就好了
Cooky
2020-02-06 19:21:44 +08:00
搜一下 expect 模块
subprocess 可以实现,但是我忘了(
CallMeReznov
2020-02-06 19:36:19 +08:00
搜索 LS 的关键字 就可以了
Death
2020-02-06 19:46:24 +08:00
pwntools 能做到
oIMOo
2020-02-06 20:20:59 +08:00
@Cooky #2 @CallMeReznov #3

output = subprocess.Popen(['python', './A.py'], stdout=subprocess.PIPE ).communicate()[0]
print(output)
我搜到大部分都是这个,然而第一行就阻塞了- -

来源于 https://stackoverflow.com/questions/4408377/how-can-i-get-terminal-output-in-python

用一个人发了另一种办法,写到临时文件,确实比 tee 好一点- -
fzinfz
2020-02-06 20:48:44 +08:00
muzuiget
2020-02-06 21:31:23 +08:00
这不就是普通的管道处理吗?难道楼主写输出时没有 flush ?
omph
2020-02-06 21:33:13 +08:00
[Pexpect 模块使用说明]( https://www.jianshu.com/p/cfd163200d12)
mxalbert1996
2020-02-06 21:35:09 +08:00
不就是 Popen 然后 communicate 吗? Popen 怎么可能阻塞? communicate 带个 timeout 然后循环就好。
oIMOo
2020-02-06 21:40:40 +08:00
@Cooky #2
@CallMeReznov #3
@muzuiget #7

https://www.heypasteit.com/clip/0IUD26

上面连接是代码,很尴尬的卡在了 read 那一行(带注释)。
如果去掉这一行,A 就可以顺利接受发过去的 888,并结束运行。


@fzinfz #6
我看同一个帖子,带 Popen 里添加 bufsize=1 看起来是一个效果,我就加上了。
不过目前好像不是这个的原因- -
oIMOo
2020-02-06 21:41:39 +08:00
@mxalbert1996 #9
感谢回复,我暂时没用到 communicate,但是试过 wait。
我的代码在 #10.
卡在了 read 那一行……
leiz
2020-02-06 21:51:21 +08:00
试试
python -u
oIMOo
2020-02-06 21:57:44 +08:00
@mxalbert1996 #9
我去读了下文档 docs[dot]python[dot]org[slash]2[slash]library[slash]subprocess[dot]html
并且尝试了一下,如果把带注释的 read 行替换成 communicate(timeout=1.0), 会直接因为 A 文件的 input 报错
```
x value: Traceback (most recent call last):
File "./A[dot]py", line 2, in <module>
x = input("x value: ")
EOFError: EOF when reading a line
lxy42
2020-02-06 22:12:54 +08:00
阻塞的原因是 A.py 需要 input, 因此在 B.py 使用 subprocess 执行 A.py 需要写数据到 stdin, 例如 subprocess.Popen.communicate 的 input 参数.
oIMOo
2020-02-06 22:13:57 +08:00
@omph #8
感谢,第一次看到这个包~
不过以下代码,什么都没有发生,哭……

cmd = "python ./tmp.py"
process = pexpect.spawn(cmd, logfile=sys.stdout)
process.logfile_read = sys.stdout
oIMOo
2020-02-06 22:16:39 +08:00
@lxy42 #14

根据错误提示,我也感觉是这个原因。
但是我的 input 的参数,需要根据 A 中 input 语句来进行判断。
比如说 x value 我给它 666, 说 y value 我给它 888.

这么一来,好像就不能用 communite,而是单独用 read 和 write。
但是呢…… 就卡住了- -

---

我把 input 改成 print(提示) 和 input() 试试……
lxy42
2020-02-06 22:34:34 +08:00
@oIMOo subprocess 不太适合这种两个进程频繁通信的情况, 可以考虑使用 RPC.
chibupang
2020-02-06 22:48:41 +08:00
A 在 input 之后输出提示到 tmp.txt ,B 读取 tmp.txt ,获得 A 的输出。
chibupang
2020-02-06 22:49:41 +08:00
相当于记录 A 的日志,B 读取 A 的日志。
oIMOo
2020-02-06 22:51:50 +08:00
@chibupang #18
这个是最初的办法,我最最开始用的 tee 命令。
后来经过提示,发现了 #5 的临时文件方法。

不过如果有不需要提三个文件的办法,那就最好了。

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

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

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

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

© 2021 V2EX