63908

Can pexpect be told to ignore a pattern or signal?

I'm trying to write a python script to access several Cisco network devices. Sadly the devices are not set up the same, some have banners up that appear at weird places. These banners might have the patterns that have some of the same stuff a prompt might have.

For example, once I log in I expect a prompt of 'hostname#', so I basically use a pexpect('#') I might have to handle certain other prompts such as 'hostname>' as well so pexpect('>') works. I'll really have a list of possible prompts, plus a timeout and act accordingly.

This is fine unless a banner shows up in the middle somewhere. For example, after logging in a banner might show up that says ## Welcome ## and be there right before the prompt. I believe if I could tell pexpect to ignore the regular expression #.*\r I'd be fine, but I'm not sure this is possible. Is it possible to have pexpect ignore a string, or is there a better way to go about this?

Answer1:

A solution I used to use back in the BBS days was to look for a prompt, and then immediately after I got one, look for a line break or a space with a timeout of a second or two. If the second wait timed out, that meant I was waiting at a prompt. Since pexpect uses regular expressions, you can actually check to see if you receive any character within a second after a prompt.

def wait_for_prompt(session, prompt, timeout=1): gotprompt = 0 while not gotprompt: session.expect(prompt, timeout=None) gotprompt = session.expect([".", pexpect.TIMEOUT], timeout=timeout) child = pexpect.spawn("ssh ...") wait_for_prompt(child, "[#>]")

I've never actually used this library before so this may need some tweaking, but it's an approach I used successfully in the '80s. :-)

Answer2:

The Python pexpect module waits for matching input. You can't actually ignore input, except by creating regular expressions that will not match ambiguous or undesirable input. Instead of creating one really complex regex, though, pexpect can also handle lists of regular expressions. You then anchor those regular expressions to reduce ambiguity.

For example, you can easily differentiate between a command prompt and a banner by anchoring the match to the start or end of the line, and making the match as exact as possible:

users = ['fred', 'ginger'] user_prompt = '^(?:%s)@.*?\$ $' % '|'.join(users) child.expect (['hostname# $', 'hostname> $', user_prompt])

They key is to understand what input you want to match, build an unambiguous regular expression with anchors, and then update your expressions whenever you find a mismatch--which hopefully won't be too often because you didn't create overly-greedy patterns in the first place.

Answer3:

Once expect has found a match it sets the 'before', 'after', and 'match' attributes on the process instance. You could use these to write some logic.

Alternatively you could just craft a better regex that only matches the prompt that you want. Even r'>$|#$' would probably do what you want since it is only going to match those characters at the end of a line.

Recommend

  • System call interception in linux-kernel module (kernel 3.5)
  • Hiding Ad Banner causes no further Ads to be requested/shown
  • change css style on click with jquery
  • iAD View Freezes On Ad Close
  • jquery - Use split to split only text?
  • Admob not generating visuals
  • Need to display 2 diff banner sprites on same page based on the value of a control of Master Page
  • Toggle menu Button doesn't open sliding menu and shuts down app
  • Spring Boot JSP 404.Whitelabel Error Page
  • percent (%) width rendered differently in different browser (firefox, safari, opera, chrome)
  • When will it become active on admob at Android app
  • (oracle) insert in stored procedure very slow compared to insert run manually
  • Exit from a loop that contains time delay immediately after a key is pressed
  • Is there a way to pivot a customer ID and a their most recent order dates?
  • Authentication - JavaScript - Logout issue
  • phpmailer - How to verify a sent email arrived at its destination
  • Using an STL Iterator without initialising it
  • How to access culture data in globalize.js V1.0.0
  • NUnit 3.0 TestCase const custom object arguments
  • Plotting line graph with factors in R
  • Position: fixed nav does not stay fixed
  • Date Conversion from yyyy-mm-dd to dd-mm-yyyy
  • Debug.DrawLine not showing in the GameView
  • print() is showing quotation marks in results
  • Can you perform a UNION without a subquery in SQLAlchemy?
  • FFmpeg Conversion Error
  • How do I fake an specific browser client when using Java's Net library?
  • How reduce the height of an mschart by breaking up the y-axis
  • Excel - Autoshape get it's name from cell (value)
  • Check if a string to interpolate provides expected placeholders
  • Perl system calls when running as another user using sudo
  • Updated Ionic CLI but shows previous version (Windows)
  • RestKit - RKRequestDelegate does not exist
  • AT Commands to Send SMS not working in Windows 8.1
  • Traverse Array and Display in markup
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Setting background image for body element in xhtml (for different monitors and resolutions)
  • Can Visual Studio XAML designer handle font family names with spaces as a resource?
  • apache spark aggregate function using min value
  • Sorting a 2D array using the second column C++