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 进行处理……

6524 次点击
所在节点    Python
29 条回复
chibupang
2020-02-06 23:02:46 +08:00
那可以考虑使用 socket 通信,A 在 input 的时候并不是真的 input,而是将提示发送给 B,B 接收到提示后,可以从键盘输入,也可以自动设置 token,并把结果返回,这样 A 的输入就完全交给 B 去实现了。
(不知道你的具体场景是什么。
oIMOo
2020-02-06 23:09:44 +08:00
@chibupang #21
访问一个 API: 需要通过 API 给出的链接 -> 登陆 -> 获取 PIN -> 在终端里输入。
每次(每个 session )都会生成新链接,然后重新获取 PIN。

中间部分,登陆 + 获取 PIN,我是没问题的。
然而怎么拿到链接卡住了……
简化下来就是主题里 A.py 的场景。
chibupang
2020-02-06 23:21:14 +08:00
a@oIMOo #22 根据你的描述,A 应该是可以得到每次的新链接,那么只需要把这个链接发送给 B,B 去访问这个链接,完成登录,返回 PIN 给 A。
oIMOo
2020-02-06 23:27:30 +08:00
@chibupang #23
对的,但是你看我 append 的代码,我抓不到这个链接……
应该说我抓不到 所有 仍在运行的输出……
omph
2020-02-07 09:55:13 +08:00
我试了下,expect 模块应该可以吧,只用 expect 脚本试了下

```
#!/bin/expect -f

set timeout 5;
spawn python A.py;
expect {
"*Value x:*" { send 3\r; exp_continue; }
eof { exit 0; }
}
``
noclin
2020-02-07 12:01:09 +08:00
test1.py
```
print(input("input1\n"))

print(input("input2\n"))
```

test2.py
```
import subprocess

p = subprocess.Popen(["python", "test1.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True,
bufsize=1)

while p.poll() is None:
line = p.stdout.readline()
print("[out]", line.encode())
if line == "input1\n":
p.stdin.write("hello\n")
p.stdin.flush()
elif line == "input2\n":
p.stdin.write("world\n")
p.stdin.flush()
```
试一下这样?要注意输出必须有\n 不然会卡在 read
noclin
2020-02-07 15:45:10 +08:00
再附加一条,没有换行存在阻塞的情况,要按单个字符读取,存入暂存区自己判断即可
```
import subprocess

p = subprocess.Popen(["python", "a.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True,
bufsize=1)

stash = ""
while p.poll() is None:
c = p.stdout.read(1)
stash += c
print(c, end='')
if stash == "Value x: ":
print()
print("[bingo]", stash)
stash = ""
p.stdin.write("hello\n")
```


输出

```
Value x:
[bingo] Value x:
x = hello
```
oIMOo
2020-02-07 16:28:12 +08:00
@noclin #27
我电脑有毒,依然不行…… 为了找到哪里阻塞,我试了一个只有四行的版本:

import subprocess
p = subprocess.Popen(['python', './A[dot]py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True, bufsize=1)
c = p.stdout.read(1)
print(c, end='')

然而还是不行,我就开始检查环境之旅…… 发现是 python 的问题……
目前已解决,我写在 append 里面去。
oIMOo
2020-02-07 16:42:33 +08:00
感谢所有朋友的帮助,问题已解决,原因在 append 中。
@wuwukai007 #1 @Cooky #2 @CallMeReznov #3 @fzinfz #6 @muzuiget #7 @mxalbert1996 #9 @leiz #12 @lxy42 #14 @noclin #26

@omph #8
感谢,一直在研究 subprocess,我也看一下 Pexpect

@chibupang #18
socket 不太适合我这个场景( A[dot]py 在实际中不能变更),但是也非常感谢!

@Death #4
pwntools 当年学安全的时候用过,现在全都忘光了哈哈哈,我再去捡起来。

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

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

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

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

© 2021 V2EX