admin管理员组文章数量:1122846
I want to have two scripts communicating by exchanging messages. I have to use pexpect because of other restrictions. I am trying to make a minimal working example before I build it out for my application.
I have tried to do a minimal working example by following the tutorials I could find on the internet. But I've failed and here is my attempt.The first script is the one that initiates communication:
#script_1.py
import pexpect
p = pexpect.spawn("python /path/to/script/script_2.py")
p.expect(">")
p.sendline(input("Message to the other script: "))
print( p.before )
Here is the second script which should receive communication and send answer:
#script_2.py
indata = input(">")
print(indata)
How can I make two python scripts communicate by using pexpect?
EDIT: I was asked why I say that the scripts fail given that there are no error messages. The reason it is a failure is that script 2 should echo the message sent by script 1, and script 1 should print out (or in other ways capture the response), but that doesn't happen
I want to have two scripts communicating by exchanging messages. I have to use pexpect because of other restrictions. I am trying to make a minimal working example before I build it out for my application.
I have tried to do a minimal working example by following the tutorials I could find on the internet. But I've failed and here is my attempt.The first script is the one that initiates communication:
#script_1.py
import pexpect
p = pexpect.spawn("python /path/to/script/script_2.py")
p.expect(">")
p.sendline(input("Message to the other script: "))
print( p.before )
Here is the second script which should receive communication and send answer:
#script_2.py
indata = input(">")
print(indata)
How can I make two python scripts communicate by using pexpect?
EDIT: I was asked why I say that the scripts fail given that there are no error messages. The reason it is a failure is that script 2 should echo the message sent by script 1, and script 1 should print out (or in other ways capture the response), but that doesn't happen
Share Improve this question edited Nov 23, 2024 at 2:36 Mikkel Rev asked Nov 23, 2024 at 1:47 Mikkel RevMikkel Rev 9013 gold badges14 silver badges31 bronze badges 17 | Show 12 more comments2 Answers
Reset to default 1Your difficulty revolves around buffering of the >
prompt.
The 2nd script does not quickly send it, so the 1st script doesn't see it.
Let us alter the scripts slightly, so they look like this. And assume the user types in "apples".
script_2.py
print("ok1")
indata = input(">")
print("I like", indata, ".")
print("ok2")
script_1.py
import pexpect
p = pexpect.spawn("python /path/to/script_2.py")
p.expect("ok1")
assert p.before == b""
assert p.after == b"ok1"
p.sendline(input("Message to the other script: "))
p.expect("ok2")
assert p.before == b"\r\n>apples\r\nI like apples .\r\n"
assert p.after == b"ok2"
assert p.buffer == b"\r\n"
(I started out with just "ok", then realized I needed two distinct strings.)
What is different, here?
The print()
with a newline is flushing the buffer to stdout,
so that script_1 has an opportunity to see the string
it is looking for.
An implementation of script1 using asyncio -- note that the logging to stderr is for your use as a human reader to follow how the flow of control crosses processes:
#!/usr/bin/env python
import asyncio
import asyncio.subprocess
import sys
# taken from https://stackoverflow.com/a/65326191/14122
async def ainput(string: str) -> str:
await asyncio.get_event_loop().run_in_executor(None, lambda: sys.stderr.write(string))
return await asyncio.get_event_loop().run_in_executor(None, sys.stdin.readline)
async def aoutput(string: str) -> None:
await asyncio.get_event_loop().run_in_executor(None, lambda: sys.stderr.write(string))
async def run():
p = await asyncio.create_subprocess_exec('./script2.py', stdin=asyncio.subprocess.PIPE, stdout=asyncio.subprocess.PIPE)
while True:
print("script1: waiting for user input", file=sys.stderr)
request = await ainput('Message to other script: ')
print("script1: got user input, writing to script2", file=sys.stderr)
p.stdin.write((request.rstrip('\n') + '\n').encode())
await p.stdin.drain()
print("script1: sent input to script2, waiting for response", file=sys.stderr)
response = await p.stdout.readline()
print("script1: got response from script2", file=sys.stderr)
await aoutput(f'Got response: {response!r}\n')
asyncio.run(run())
...and a version of script2 that loops, to make it worthwhile:
#!/usr/bin/env python3
import sys
while True:
print("script2: waiting for input on stdin", file=sys.stderr)
indata = input() # Why would you bother printing a prompt when there's no human?
print("script2: writing output to stdout", file=sys.stderr)
print(f'Output data: <{indata!s}>')
When run, output looks like:
$ python3 script1.py
script1: waiting for user input
script2: waiting for input on stdin
I just typed this as the first line of content
Message to other script: script1: got user input, writing to script2
script1: sent input to script2, waiting for response
script2: writing output to stdout
script2: waiting for input on stdin
script1: got response from script2
Got response: b'Output data: <I just typed this as the first line of content>\n'
script1: waiting for user input
I just typed this as the second line of content
Message to other script: script1: got user input, writing to script2
script1: sent input to script2, waiting for response
script2: writing output to stdout
script2: waiting for input on stdin
script1: got response from script2
Got response: b'Output data: <I just typed this as the second line of content>\n'
script1: waiting for user input
本文标签: automationexpect make two python scripts communicateStack Overflow
版权声明:本文标题:automation - expect: make two python scripts communicate - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736300073a1930687.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
expect
is the most optimal option by any reasonable measure. Can you link the questions from Stack Overflow on which you mention you’re basing this claim? – esqew Commented Nov 23, 2024 at 1:55ftp
was designed to be driven by humans, so using expect when automating interactions with it is appropriate (not as appropriate as using a native Python FTP library, but if we assume you have to use the external ftp program for some reason, expect is a reasonable choice). But if you're designing both the programs, you're in a different situation. – Charles Duffy Commented Nov 23, 2024 at 2:34subprocess.Popen
. There's no call for expect. – Charles Duffy Commented Nov 23, 2024 at 2:40subprocess.Popen
, you just can't usecommunicate()
. – Charles Duffy Commented Nov 23, 2024 at 2:40