考虑一个简单的应用程序,它具有一些基本的执行控制流,只是将其 STDIN 与 STDOUT 反向回显 - 这可以是任何可执行文件,但为了简单起见,我们将坚持使用 Python - 例如,app.py:
#!/usr/bin/env python
import sys
sys.stdout.write("::BEGIN::\n") # tell our listener that we're listening...
sys.stdout.flush() # flush the STDOUT buffer
while True: # a simple event loop
line = sys.stdin.readline().rstrip() # read a line from STDIN
if line: # ignore empty lines
if line == "::END::": # just a convenient way to shut down the app
sys.stdout.write("::END::\n") # tell our listener that we're done
sys.stdout.flush() # flush the STDOUT buffer
break # we're finished here
sys.stdout.write(line[::-1]) # write the reversed line to STDOUT
sys.stdout.write("\n") # add a new line to the STDOUT
sys.stdout.flush() # flush the STDOUT buffer
如果你想打开这个应用程序并通过你的 Python 脚本与它通信,你需要做的就是控制子进程 STDOUT 和 STDIN,你可以无限期地这样做,例如:
import subprocess
# start our subprocess, forward its STDOUT and STDIN to the internal buffers
proc = subprocess.Popen(["python", "app.py"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
# lets define our data to be sent one by one to our app.py, including ::END:: to exit...
items = ["test", "data", "to", "run", "sequentially", "::END::"]
# a convenience function to get the next item and write it to the passed buffer
def send_next_item(buf):
item = items.pop(0) # pop the first element from `items`
print("REQ: {}".format(item))
buf.write(item) # write it to the passed buffer
buf.write("\n") # write a new line to the passed buffer
buf.flush() # flush the passed buffer
while True: # wait for a prompt by our app
line = proc.stdout.readline().rstrip()
if line == "::BEGIN::":
print("BEGIN!")
send_next_item(proc.stdin) # send the first item to the processes' STDIN
elif line == "::END::":
print("END!")
break # nothing more to do
elif line: # ignore empty lines
print("RES: {}".format(line))
send_next_item(proc.stdin) # send the next item to the processes' STDIN
当你运行它时,你会得到如下输出:
开始!
请求:测试
资源:tset
请求:数据
RES: atad
请求:到
回复:过
请求:运行
RES: 努尔
请求:顺序
RES: 伊莱特纽克斯
请求:::END::
结束!
当然,你可以做进一步的处理来决定如何正确响应被调用应用的输入请求,这只是一个基本的例子。