Python Forum
Not able to read the text using pexpect/expect - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Not able to read the text using pexpect/expect (/thread-35980.html)



Not able to read the text using pexpect/expect - Bipinjohnson - Jan-06-2022

Hi,
I am new to python i am trying some automation where in i want to call a terminal application from python and control the same.
I have tried Pexpect where i am able to open the application, but not able to read the contents from the terminal.
pasted below is my code:

import pexpect

child = pexpect.spawn ('./test_app -g',timeout=3,encoding='utf-8')
#i am expecting the below string
return_val=child.expect(['Enable QSE API? (Y/n)'])
#if i receive the same string then i want to pass y to the terminal
child.sendline('y')

#now i am expecting the below string
child.expect('Enable log? (Y/n)')
child.sendline("y")
When i execute the above script always timeout occurs and gets the below erorr/log message:

Error:
user@user-laptop:~/Automation$ python3 script_v1.py Traceback (most recent call last): File "script_v1.py", line 5, in <module> return_val=child.expect(['Enable QSE API? (Y/n)']) File "/usr/local/lib/python3.6/site-packages/pexpect/spawnbase.py", line 344, in expect timeout, searchwindowsize, async_) File "/usr/local/lib/python3.6/site-packages/pexpect/spawnbase.py", line 372, in expect_list return exp.expect_loop(timeout) File "/usr/local/lib/python3.6/site-packages/pexpect/expect.py", line 181, in expect_loop return self.timeout(e) File "/usr/local/lib/python3.6/site-packages/pexpect/expect.py", line 144, in timeout raise exc pexpect.exceptions.TIMEOUT: Timeout exceeded. <pexpect.pty_spawn.spawn object at 0x7fae358ece10> command: ./test_app args: [b'./test_app', b'-g'] buffer (last 100 chars): '\x1b[2J\x1b[1dEnable QSE API? (Y/n) ' before (last 100 chars): '\x1b[2J\x1b[1dEnable QSE API? (Y/n) ' after: <class 'pexpect.exceptions.TIMEOUT'> match: None match_index: None exitstatus: None flag_eof: False pid: 7737 child_fd: 5 closed: False timeout: 3 delimiter: <class 'pexpect.exceptions.EOF'> logfile: None logfile_read: None logfile_send: None maxread: 2000 ignorecase: False searchwindowsize: None delaybeforesend: 0.05 delayafterclose: 0.1 delayafterterminate: 0.1 searcher: searcher_re: 0: re.compile('Enable QSE API? (Y/n)') user@user-laptop:~/Automation$
Something about the application: It runs on Ubuntu 18.x.x. terminal, once its started it will publish a menu and the user have to input the menu options.
Note: When i am tying to run the application manually, everything works fine.


Looking forward for some guidance from experts.


Regards
Johnson


RE: Not able to read the text using pexpect/expect - lucasbazan - Jan-06-2022

Hii. U can use subprocess lib to start some process.

from subprocess import Popen, PIPE


process = Popen(['test_app', '-g'], stdout=PIPE, stderr=PIPE)
stdout = process.communicate()

print(stdout)
The list inside Popen class is the arguments that you want to performs.

If you want more information you can access https://docs.python.org/3/library/subprocess.html

Hope this helps Tongue


RE: Not able to read the text using pexpect/expect - ibreeden - Jan-07-2022

Hi @Bipinjohnson ,
In the documentation of expect() you can read:
Quote:Strings will be compiled to re types
. This means your expected string is a dangerous one because it will be treated as a regular expression:
'Enable QSE API? (Y/n)'
The question mark means the previous character must appear 0 or 1 time. The parenthesis also have a meaning of capturing substrings. So you should escape those characters:
'Enable QSE API\? \(Y\/n\)'
I am not sure if this works. Play it safe and just check for:
'Enable QSE API'

Then also: you do not check if the string is found. You should check the returned value.
return_val=child.expect(['Enable QSE API'])
#if i receive the same string then i want to pass y to the terminal
if return_val == 0:
    child.sendline('y')
else:
    print("The expected string was not found")
    sys.exit()



RE: Not able to read the text using pexpect/expect - Bipinjohnson - Jan-07-2022

Hi Tim/lucasbazan,
Thank you for your response.
I tried your suggestion but its not working for me.
I gone through the documentation and try adding few more arguments to the code, but still no luck. Pasted below is my code
from subprocess import Popen, PIPE

process=Popen(['/home/user/Automation/test_app', '-g'], stdout=PIPE, stderr=PIPE, stdin=PIPE, shell=True, universal_newlines=True)
print("return value",process)
stdout=process.communicate(input='y',timeout=3)
print(stdout)
while executing the code i am always getting timeout and pasted below is the error message /log.
Error:
user@user-laptop:~/Automation$ python3 sub.py return value <subprocess.Popen object at 0x7f8dd3046240> Traceback (most recent call last): File "sub.py", line 6, in <module> stdout=process.communicate(input='y',timeout=3) File "/usr/local/lib/python3.6/subprocess.py", line 843, in communicate stdout, stderr = self._communicate(input, endtime, timeout) File "/usr/local/lib/python3.6/subprocess.py", line 1515, in _communicate self._check_timeout(endtime, orig_timeout) File "/usr/local/lib/python3.6/subprocess.py", line 871, in _check_timeout raise TimeoutExpired(self.args, orig_timeout) subprocess.TimeoutExpired: Command '['/home/user/Automation/test_app', '-g']' timed out after 3 seconds user@user-laptop:~/Automation$
Note: After the error is occurring i am not able to run the script again in the same terminal, may be the process might me running in the background and occupying it.

Any other suggestions to solve this? Is there any way to know whether the executable got executed?
Or is there any way to see that message("Enable QSE API? (Y/n)" in the terminal itself?


RE: Not able to read the text using pexpect/expect - Bipinjohnson - Jan-07-2022

Hi Larz60+,
Sorry for my oversight, i will take care of your suggestions hereafter.
Regards
Johnson


RE: Not able to read the text using pexpect/expect - Bipinjohnson - Jan-07-2022

Hi Ibreeden,
I tried your suggestion, but looks like its again getting timed out
pasted below is my code and its error message.
import pexpect

child = pexpect.spawn ('./test_app -g', encoding='utf-8',timeout=3)
return_val=child.expect(["Enable QSE API? (Y/n)"])
print("After expect",return_val)
if return_val==0:
	child.sendline('y')
else:
    print("The expected string was not found")
    sys.exit()

return_val=child.expect('Enable log? (Y/n)')
if return_val==0:
	child.sendline('y')
else:
    print("The expected string was not found")
    sys.exit()
Error message /log:
Error:
Traceback (most recent call last): File "script_new.py", line 7, in <module> return_val=child.expect(["Enable QSE API? (Y/n)"]) File "/usr/local/lib/python3.6/site-packages/pexpect/spawnbase.py", line 344, in expect timeout, searchwindowsize, async_) File "/usr/local/lib/python3.6/site-packages/pexpect/spawnbase.py", line 372, in expect_list return exp.expect_loop(timeout) File "/usr/local/lib/python3.6/site-packages/pexpect/expect.py", line 181, in expect_loop return self.timeout(e) File "/usr/local/lib/python3.6/site-packages/pexpect/expect.py", line 144, in timeout raise exc pexpect.exceptions.TIMEOUT: Timeout exceeded. <pexpect.pty_spawn.spawn object at 0x7f2eb4d2a1d0> command: ./test_app args: [b'./test_app', b'-g'] buffer (last 100 chars): '\x1b[2J\x1b[1dEnable QSE API? (Y/n) ' before (last 100 chars): '\x1b[2J\x1b[1dEnable QSE API? (Y/n) ' after: <class 'pexpect.exceptions.TIMEOUT'> match: None match_index: None exitstatus: None flag_eof: False pid: 11380 child_fd: 5 closed: False timeout: 3 delimiter: <class 'pexpect.exceptions.EOF'> logfile: None logfile_read: None logfile_send: None maxread: 2000 ignorecase: False searchwindowsize: None delaybeforesend: 0.05 delayafterclose: 0.1 delayafterterminate: 0.1 searcher: searcher_re: 0: re.compile('Enable QSE API? (Y/n)')
Why its not even printing the return value? Also in the error message what are those extra characters (\x1b[2J\x1b[1dEnable QSE API? (Y/n) )?
Any other thoughts from your side to solve this?


RE: Not able to read the text using pexpect/expect - ibreeden - Jan-07-2022

(Jan-07-2022, 06:34 PM)Bipinjohnson Wrote: Also in the error message what are those extra characters (\x1b[2J\x1b[1dEnable QSE API? (Y/n) )?
These are probably ANSI terminal escape sequences. Never mind about them, it's a long story.

My suggestion was to shorten the expect string in line 4:
return_val=child.expect(["Enable QSE API"])
This should be enough to recognize the line. If it works you should also strip all characters that activate regular expressions from line 12. Oh and make it also a list by adding square brackets, otherwise the return code may not be zero.
And also: Are you sure a timeout of 3 seconds is sufficient? What happens if you leave the timout default (30)?


RE: Not able to read the text using pexpect/expect - Bipinjohnson - Jan-10-2022

Hi ibreeden
Thanks a lot for that suggestion, it worked by shortening the expected string.

Note: it was not the timeout , i have already tried increasing the timeout.
Regards
Johnson