各位好。
提问前,我已经 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 进行处理……
1
wuwukai007 2020-02-06 19:19:30 +08:00
同一个文件可以吧,处理完后调用 os.system("clear")不就好了
|
2
Cooky 2020-02-06 19:21:44 +08:00 via Android
搜一下 expect 模块
subprocess 可以实现,但是我忘了( |
3
CallMeReznov 2020-02-06 19:36:19 +08:00
搜索 LS 的关键字 就可以了
|
4
Death 2020-02-06 19:46:24 +08:00 via Android
pwntools 能做到
|
5
oIMOo OP @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 好一点- - |
6
fzinfz 2020-02-06 20:48:44 +08:00
试下 PYTHONUNBUFFERED=1
ref: https://stackoverflow.com/questions/803265/getting-realtime-output-using-subprocess |
7
muzuiget 2020-02-06 21:31:23 +08:00
这不就是普通的管道处理吗?难道楼主写输出时没有 flush ?
|
8
omph 2020-02-06 21:33:13 +08:00
[Pexpect 模块使用说明]( https://www.jianshu.com/p/cfd163200d12)
|
9
mxalbert1996 2020-02-06 21:35:09 +08:00 via Android
不就是 Popen 然后 communicate 吗? Popen 怎么可能阻塞? communicate 带个 timeout 然后循环就好。
|
10
oIMOo OP @Cooky #2
@CallMeReznov #3 @muzuiget #7 https://www.heypasteit.com/clip/0IUD26 上面连接是代码,很尴尬的卡在了 read 那一行(带注释)。 如果去掉这一行,A 就可以顺利接受发过去的 888,并结束运行。 @fzinfz #6 我看同一个帖子,带 Popen 里添加 bufsize=1 看起来是一个效果,我就加上了。 不过目前好像不是这个的原因- - |
11
oIMOo OP |
12
leiz 2020-02-06 21:51:21 +08:00
试试
python -u |
13
oIMOo OP @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 |
14
lxy42 2020-02-06 22:12:54 +08:00
|
15
oIMOo OP |
16
oIMOo OP @lxy42 #14
根据错误提示,我也感觉是这个原因。 但是我的 input 的参数,需要根据 A 中 input 语句来进行判断。 比如说 x value 我给它 666, 说 y value 我给它 888. 这么一来,好像就不能用 communite,而是单独用 read 和 write。 但是呢…… 就卡住了- - --- 我把 input 改成 print(提示) 和 input() 试试…… |
18
chibupang 2020-02-06 22:48:41 +08:00 via iPhone
A 在 input 之后输出提示到 tmp.txt ,B 读取 tmp.txt ,获得 A 的输出。
|
19
chibupang 2020-02-06 22:49:41 +08:00 via iPhone
相当于记录 A 的日志,B 读取 A 的日志。
|
20
oIMOo OP |
21
chibupang 2020-02-06 23:02:46 +08:00 via iPhone
那可以考虑使用 socket 通信,A 在 input 的时候并不是真的 input,而是将提示发送给 B,B 接收到提示后,可以从键盘输入,也可以自动设置 token,并把结果返回,这样 A 的输入就完全交给 B 去实现了。
(不知道你的具体场景是什么。 |
22
oIMOo OP |
23
chibupang 2020-02-06 23:21:14 +08:00 via iPhone
a@oIMOo #22 根据你的描述,A 应该是可以得到每次的新链接,那么只需要把这个链接发送给 B,B 去访问这个链接,完成登录,返回 PIN 给 A。
|
24
oIMOo OP |
25
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; } } `` |
26
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 |
27
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 ``` |
28
oIMOo OP @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 里面去。 |
29
oIMOo OP 感谢所有朋友的帮助,问题已解决,原因在 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 当年学安全的时候用过,现在全都忘光了哈哈哈,我再去捡起来。 |