Python Forum
Not able to read the text using pexpect/expect
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Not able to read the text using pexpect/expect
#1
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
Larz60+ write Jan-06-2022, 11:04 PM:
Please post all code, output and errors (it it's entirety) between their respective tags. Refer to BBCode help topic on how to post. Use the "Preview Post" button to make sure the code is presented as you expect before hitting the "Post Reply/Thread" button.
Fixed for you this time. Please use bbcode tags on future posts.
Reply
#2
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
[Image: LEHoEPo.jpg]
Reply
#3
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()
Reply
#4
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?
Reply
#5
Hi Larz60+,
Sorry for my oversight, i will take care of your suggestions hereafter.
Regards
Johnson
Reply
#6
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?
Reply
#7
(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)?
Reply
#8
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
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Reading and storing a line of output from pexpect child eagerissac 1 4,145 Feb-20-2024, 05:51 AM
Last Post: ayoshittu
  Read text file, modify it then write back Pavel_47 5 1,500 Feb-18-2023, 02:49 PM
Last Post: deanhystad
  read a text file, find all integers, append to list oldtrafford 12 3,369 Aug-11-2022, 08:23 AM
Last Post: Pedroski55
  Use pexpect to send user input alisha17 0 1,826 May-10-2022, 02:44 AM
Last Post: alisha17
  Sudden Problem with pexpect gw1500se 3 2,322 Nov-19-2021, 11:21 PM
Last Post: bowlofred
  How to use pexpect in python? tiho_bg 1 1,489 Oct-30-2021, 02:50 PM
Last Post: Yoriz
  [SOLVED] Read text file from some point till EOF? Winfried 1 1,911 Oct-10-2021, 10:29 PM
Last Post: Winfried
  Open and read multiple text files and match words kozaizsvemira 3 6,671 Jul-07-2021, 11:27 AM
Last Post: Larz60+
  Pexpect timesout before executing whole output eagerissac 0 1,453 Jun-23-2021, 03:30 AM
Last Post: eagerissac
  pexpect startup help korenron 2 3,431 Apr-27-2021, 07:23 AM
Last Post: korenron

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020