I've been struggling lately with the following in Python: I need to interact with a 3rd party program (an executable) which needs some arguments for controlling external HW. I'm able to communicate with this exe through subprocess functions passing arguments as expected by the exe. However, when running some tests, due to fail in the test results, I could see it was related to the fact that I'm passing all the arguments too quickly to the exe whereas it needs some time to process it in between args. I'm not sure my explanations are clear enough, I'll post some examples. I need to pass the type of the HW, its port COM and some other informations. This is the prompt from the exe:
Enter reader type: 2 Enter COM port (e.g. COM3): COM3
After the COM port argument is passed, it can take up to 3-8 seconds to activate the HW correctly. Then I need to pass other arguments. The problem is when I send all the arguments at once, the HW responds sometimes as busy and don't take all the arguments. Ideally, I should add a delay after passing the port COM argument but didn't manage to do it. This is where I would need some help, please.
Here is the code I'm using in the main :
_, op, er = _run_cisc_command_timeout([executable],
[reader + "\n", com + "\n", amount + "\n", timeout + "\n", "-1\n", "a\n"],1000)
value = "".join(op)
and this is the function dealing with the HW:
p = subprocess.Popen(_args, shell=withShell,
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
if debug:
for v in input:
print("DEBUG: {}".format(v))
p.stdin.write(bytes(v, 'utf-8'))
else:
[p.stdin.write(bytes(v, 'utf-8')) for v in input]
timer = Timer(timeout, p.kill)
try:
timer.start()
stdout, stderr = p.communicate()
if debug:
print("DEBUG: {}".format(stdout))
result[index] = [p.returncode, stdout, stderr]
finally:
timer.cancel()
return True
Thanks in advance for your help/suggestions/ideas on how to process this.
[EDIT] So I tried with pexpect the following:
p = subprocess.Popen(tool, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
o = pexpect.fdpexpect.fdspawn(p.stdout.fileno())
index = o.expect(["Enter*",pexpect.TIMEOUT])
it get stucks at o.expect line as if the stdout was empty or not read ?
strong text[EDIT based on Rob answers]: here is the output when passing 'a' to the child:
a
Press any key to continue . . . a
Library Test Tool Enter reader type: Enter COM port (e.g. COM3): 2 - UNKNOWN: Reader Control Library 2 - UNKNOWN: Library 2 - UNKNOWN: Version 1.6.0.0 2 - UNKNOWN: 0 - UNKNOWN: Intialize Reader - Error: unknown reader type Failed to initialize reader - shutting down Failed to initialize reader - shutting down Traceback (most recent call last): File "C:/Data/latest_v3/run_cisc_tool.py", line 229, in cisc_pexpect_2(exec) File "C:/Data/latest_v3/run_cisc_tool.py", line 173, in cisc_pexpect_2 child.expect(["Press*", ], timeout=10) File "C:\python-3.6.8.amd64\lib\site-packages\pexpect\spawnbase.py", line 344, in expect timeout, searchwindowsize, async_) File "C:\python-3.6.8.amd64\lib\site-packages\pexpect\spawnbase.py", line 372, in expect_list return exp.expect_loop(timeout) File "C:\python-3.6.8.amd64\lib\site-packages\pexpect\expect.py", line 179, in expect_loop return self.eof(e) File "C:\python-3.6.8.amd64\lib\site-packages\pexpect\expect.py", line 122, in eof raise exc pexpect.exceptions.EOF: End Of File (EOF). <pexpect.popen_spawn.PopenSpawn object at 0x0000028A3EB02978> searcher: searcher_re: 0: re.compile(b'Press*')
and when passing correct arguments to initiate the HW I simply get the error message for the pexpect's timeout.