1*9c5db199SXin Li# Lint as: python2, python3 2*9c5db199SXin Li"""Pexpect is a Python module for spawning child applications and controlling 3*9c5db199SXin Lithem automatically. Pexpect can be used for automating interactive applications 4*9c5db199SXin Lisuch as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup 5*9c5db199SXin Liscripts for duplicating software package installations on different servers. It 6*9c5db199SXin Lican be used for automated software testing. Pexpect is in the spirit of Don 7*9c5db199SXin LiLibes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python 8*9c5db199SXin Lirequire TCL and Expect or require C extensions to be compiled. Pexpect does not 9*9c5db199SXin Liuse C, Expect, or TCL extensions. It should work on any platform that supports 10*9c5db199SXin Lithe standard Python pty module. The Pexpect interface focuses on ease of use so 11*9c5db199SXin Lithat simple tasks are easy. 12*9c5db199SXin Li 13*9c5db199SXin LiThere are two main interfaces to Pexpect -- the function, run() and the class, 14*9c5db199SXin Lispawn. You can call the run() function to execute a command and return the 15*9c5db199SXin Lioutput. This is a handy replacement for os.system(). 16*9c5db199SXin Li 17*9c5db199SXin LiFor example:: 18*9c5db199SXin Li 19*9c5db199SXin Li pexpect.run('ls -la') 20*9c5db199SXin Li 21*9c5db199SXin LiThe more powerful interface is the spawn class. You can use this to spawn an 22*9c5db199SXin Liexternal child command and then interact with the child by sending lines and 23*9c5db199SXin Liexpecting responses. 24*9c5db199SXin Li 25*9c5db199SXin LiFor example:: 26*9c5db199SXin Li 27*9c5db199SXin Li child = pexpect.spawn('scp foo [email protected]:.') 28*9c5db199SXin Li child.expect ('Password:') 29*9c5db199SXin Li child.sendline (mypassword) 30*9c5db199SXin Li 31*9c5db199SXin LiThis works even for commands that ask for passwords or other input outside of 32*9c5db199SXin Lithe normal stdio streams. 33*9c5db199SXin Li 34*9c5db199SXin LiCredits: Noah Spurrier, Richard Holden, Marco Molteni, Kimberley Burchett, 35*9c5db199SXin LiRobert Stone, Hartmut Goebel, Chad Schroeder, Erick Tryzelaar, Dave Kirby, Ids 36*9c5db199SXin Livander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin, 37*9c5db199SXin LiGeoffrey Marshall, Francisco Lourenco, Glen Mabey, Karthik Gurusamy, Fernando 38*9c5db199SXin LiPerez, Corey Minyard, Jon Cohen, Guillaume Chazarain, Andrew Ryan, Nick 39*9c5db199SXin LiCraig-Wood, Andrew Stone, Jorgen Grahn (Let me know if I forgot anyone.) 40*9c5db199SXin Li 41*9c5db199SXin LiFree, open source, and all that good stuff. 42*9c5db199SXin Li 43*9c5db199SXin LiPermission is hereby granted, free of charge, to any person obtaining a copy of 44*9c5db199SXin Lithis software and associated documentation files (the "Software"), to deal in 45*9c5db199SXin Lithe Software without restriction, including without limitation the rights to 46*9c5db199SXin Liuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 47*9c5db199SXin Liof the Software, and to permit persons to whom the Software is furnished to do 48*9c5db199SXin Liso, subject to the following conditions: 49*9c5db199SXin Li 50*9c5db199SXin LiThe above copyright notice and this permission notice shall be included in all 51*9c5db199SXin Licopies or substantial portions of the Software. 52*9c5db199SXin Li 53*9c5db199SXin LiTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 54*9c5db199SXin LiIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 55*9c5db199SXin LiFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 56*9c5db199SXin LiAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 57*9c5db199SXin LiLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 58*9c5db199SXin LiOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 59*9c5db199SXin LiSOFTWARE. 60*9c5db199SXin Li 61*9c5db199SXin LiPexpect Copyright (c) 2008 Noah Spurrier 62*9c5db199SXin Lihttp://pexpect.sourceforge.net/ 63*9c5db199SXin Li 64*9c5db199SXin Li$Id: pexpect.py 507 2007-12-27 02:40:52Z noah $ 65*9c5db199SXin Li""" 66*9c5db199SXin Li 67*9c5db199SXin Lifrom __future__ import absolute_import 68*9c5db199SXin Lifrom __future__ import division 69*9c5db199SXin Lifrom __future__ import print_function 70*9c5db199SXin Li 71*9c5db199SXin Liimport six 72*9c5db199SXin Lifrom six.moves import range 73*9c5db199SXin Lifrom six.moves import zip 74*9c5db199SXin Li 75*9c5db199SXin Litry: 76*9c5db199SXin Li import os, sys, time 77*9c5db199SXin Li import select 78*9c5db199SXin Li import string 79*9c5db199SXin Li import re 80*9c5db199SXin Li import struct 81*9c5db199SXin Li import resource 82*9c5db199SXin Li import types 83*9c5db199SXin Li import pty 84*9c5db199SXin Li import tty 85*9c5db199SXin Li import termios 86*9c5db199SXin Li import fcntl 87*9c5db199SXin Li import errno 88*9c5db199SXin Li import traceback 89*9c5db199SXin Li import signal 90*9c5db199SXin Liexcept ImportError as e: 91*9c5db199SXin Li raise ImportError (str(e) + """ 92*9c5db199SXin Li 93*9c5db199SXin LiA critical module was not found. Probably this operating system does not 94*9c5db199SXin Lisupport it. Pexpect is intended for UNIX-like operating systems.""") 95*9c5db199SXin Li 96*9c5db199SXin Li__version__ = '2.3' 97*9c5db199SXin Li__revision__ = '$Revision: 399 $' 98*9c5db199SXin Li__all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'run', 'which', 99*9c5db199SXin Li 'split_command_line', '__version__', '__revision__'] 100*9c5db199SXin Li 101*9c5db199SXin Li# Exception classes used by this module. 102*9c5db199SXin Liclass ExceptionPexpect(Exception): 103*9c5db199SXin Li 104*9c5db199SXin Li """Base class for all exceptions raised by this module. 105*9c5db199SXin Li """ 106*9c5db199SXin Li 107*9c5db199SXin Li def __init__(self, value): 108*9c5db199SXin Li 109*9c5db199SXin Li self.value = value 110*9c5db199SXin Li 111*9c5db199SXin Li def __str__(self): 112*9c5db199SXin Li 113*9c5db199SXin Li return str(self.value) 114*9c5db199SXin Li 115*9c5db199SXin Li def get_trace(self): 116*9c5db199SXin Li 117*9c5db199SXin Li """This returns an abbreviated stack trace with lines that only concern 118*9c5db199SXin Li the caller. In other words, the stack trace inside the Pexpect module 119*9c5db199SXin Li is not included. """ 120*9c5db199SXin Li 121*9c5db199SXin Li tblist = traceback.extract_tb(sys.exc_info()[2]) 122*9c5db199SXin Li #tblist = filter(self.__filter_not_pexpect, tblist) 123*9c5db199SXin Li tblist = [item for item in tblist if self.__filter_not_pexpect(item)] 124*9c5db199SXin Li tblist = traceback.format_list(tblist) 125*9c5db199SXin Li return ''.join(tblist) 126*9c5db199SXin Li 127*9c5db199SXin Li def __filter_not_pexpect(self, trace_list_item): 128*9c5db199SXin Li 129*9c5db199SXin Li """This returns True if list item 0 the string 'pexpect.py' in it. """ 130*9c5db199SXin Li 131*9c5db199SXin Li if trace_list_item[0].find('pexpect.py') == -1: 132*9c5db199SXin Li return True 133*9c5db199SXin Li else: 134*9c5db199SXin Li return False 135*9c5db199SXin Li 136*9c5db199SXin Liclass EOF(ExceptionPexpect): 137*9c5db199SXin Li 138*9c5db199SXin Li """Raised when EOF is read from a child. This usually means the child has exited.""" 139*9c5db199SXin Li 140*9c5db199SXin Liclass TIMEOUT(ExceptionPexpect): 141*9c5db199SXin Li 142*9c5db199SXin Li """Raised when a read time exceeds the timeout. """ 143*9c5db199SXin Li 144*9c5db199SXin Li##class TIMEOUT_PATTERN(TIMEOUT): 145*9c5db199SXin Li## """Raised when the pattern match time exceeds the timeout. 146*9c5db199SXin Li## This is different than a read TIMEOUT because the child process may 147*9c5db199SXin Li## give output, thus never give a TIMEOUT, but the output 148*9c5db199SXin Li## may never match a pattern. 149*9c5db199SXin Li## """ 150*9c5db199SXin Li##class MAXBUFFER(ExceptionPexpect): 151*9c5db199SXin Li## """Raised when a scan buffer fills before matching an expected pattern.""" 152*9c5db199SXin Li 153*9c5db199SXin Lidef run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, cwd=None, env=None): 154*9c5db199SXin Li 155*9c5db199SXin Li """ 156*9c5db199SXin Li This function runs the given command; waits for it to finish; then 157*9c5db199SXin Li returns all output as a string. STDERR is included in output. If the full 158*9c5db199SXin Li path to the command is not given then the path is searched. 159*9c5db199SXin Li 160*9c5db199SXin Li Note that lines are terminated by CR/LF (\\r\\n) combination even on 161*9c5db199SXin Li UNIX-like systems because this is the standard for pseudo ttys. If you set 162*9c5db199SXin Li 'withexitstatus' to true, then run will return a tuple of (command_output, 163*9c5db199SXin Li exitstatus). If 'withexitstatus' is false then this returns just 164*9c5db199SXin Li command_output. 165*9c5db199SXin Li 166*9c5db199SXin Li The run() function can often be used instead of creating a spawn instance. 167*9c5db199SXin Li For example, the following code uses spawn:: 168*9c5db199SXin Li 169*9c5db199SXin Li from pexpect import * 170*9c5db199SXin Li child = spawn('scp foo [email protected]:.') 171*9c5db199SXin Li child.expect ('(?i)password') 172*9c5db199SXin Li child.sendline (mypassword) 173*9c5db199SXin Li 174*9c5db199SXin Li The previous code can be replace with the following:: 175*9c5db199SXin Li 176*9c5db199SXin Li from pexpect import * 177*9c5db199SXin Li run ('scp foo [email protected]:.', events={'(?i)password': mypassword}) 178*9c5db199SXin Li 179*9c5db199SXin Li Examples 180*9c5db199SXin Li ======== 181*9c5db199SXin Li 182*9c5db199SXin Li Start the apache daemon on the local machine:: 183*9c5db199SXin Li 184*9c5db199SXin Li from pexpect import * 185*9c5db199SXin Li run ("/usr/local/apache/bin/apachectl start") 186*9c5db199SXin Li 187*9c5db199SXin Li Check in a file using SVN:: 188*9c5db199SXin Li 189*9c5db199SXin Li from pexpect import * 190*9c5db199SXin Li run ("svn ci -m 'automatic commit' my_file.py") 191*9c5db199SXin Li 192*9c5db199SXin Li Run a command and capture exit status:: 193*9c5db199SXin Li 194*9c5db199SXin Li from pexpect import * 195*9c5db199SXin Li (command_output, exitstatus) = run ('ls -l /bin', withexitstatus=1) 196*9c5db199SXin Li 197*9c5db199SXin Li Tricky Examples 198*9c5db199SXin Li =============== 199*9c5db199SXin Li 200*9c5db199SXin Li The following will run SSH and execute 'ls -l' on the remote machine. The 201*9c5db199SXin Li password 'secret' will be sent if the '(?i)password' pattern is ever seen:: 202*9c5db199SXin Li 203*9c5db199SXin Li run ("ssh [email protected] 'ls -l'", events={'(?i)password':'secret\\n'}) 204*9c5db199SXin Li 205*9c5db199SXin Li This will start mencoder to rip a video from DVD. This will also display 206*9c5db199SXin Li progress ticks every 5 seconds as it runs. For example:: 207*9c5db199SXin Li 208*9c5db199SXin Li from pexpect import * 209*9c5db199SXin Li def print_ticks(d): 210*9c5db199SXin Li print d['event_count'], 211*9c5db199SXin Li run ("mencoder dvd://1 -o video.avi -oac copy -ovc copy", events={TIMEOUT:print_ticks}, timeout=5) 212*9c5db199SXin Li 213*9c5db199SXin Li The 'events' argument should be a dictionary of patterns and responses. 214*9c5db199SXin Li Whenever one of the patterns is seen in the command out run() will send the 215*9c5db199SXin Li associated response string. Note that you should put newlines in your 216*9c5db199SXin Li string if Enter is necessary. The responses may also contain callback 217*9c5db199SXin Li functions. Any callback is function that takes a dictionary as an argument. 218*9c5db199SXin Li The dictionary contains all the locals from the run() function, so you can 219*9c5db199SXin Li access the child spawn object or any other variable defined in run() 220*9c5db199SXin Li (event_count, child, and extra_args are the most useful). A callback may 221*9c5db199SXin Li return True to stop the current run process otherwise run() continues until 222*9c5db199SXin Li the next event. A callback may also return a string which will be sent to 223*9c5db199SXin Li the child. 'extra_args' is not used by directly run(). It provides a way to 224*9c5db199SXin Li pass data to a callback function through run() through the locals 225*9c5db199SXin Li dictionary passed to a callback. """ 226*9c5db199SXin Li 227*9c5db199SXin Li if timeout == -1: 228*9c5db199SXin Li child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env) 229*9c5db199SXin Li else: 230*9c5db199SXin Li child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile, cwd=cwd, env=env) 231*9c5db199SXin Li if events is not None: 232*9c5db199SXin Li patterns = list(events.keys()) 233*9c5db199SXin Li responses = list(events.values()) 234*9c5db199SXin Li else: 235*9c5db199SXin Li patterns=None # We assume that EOF or TIMEOUT will save us. 236*9c5db199SXin Li responses=None 237*9c5db199SXin Li child_result_list = [] 238*9c5db199SXin Li event_count = 0 239*9c5db199SXin Li while 1: 240*9c5db199SXin Li try: 241*9c5db199SXin Li index = child.expect (patterns) 242*9c5db199SXin Li if isinstance(child.after, six.string_types): 243*9c5db199SXin Li child_result_list.append(child.before + child.after) 244*9c5db199SXin Li else: # child.after may have been a TIMEOUT or EOF, so don't cat those. 245*9c5db199SXin Li child_result_list.append(child.before) 246*9c5db199SXin Li if isinstance(responses[index], six.string_types): 247*9c5db199SXin Li child.send(responses[index]) 248*9c5db199SXin Li elif type(responses[index]) is types.FunctionType: 249*9c5db199SXin Li callback_result = responses[index](locals()) 250*9c5db199SXin Li sys.stdout.flush() 251*9c5db199SXin Li if isinstance(callback_result, six.string_types): 252*9c5db199SXin Li child.send(callback_result) 253*9c5db199SXin Li elif callback_result: 254*9c5db199SXin Li break 255*9c5db199SXin Li else: 256*9c5db199SXin Li raise TypeError ('The callback must be a string or function type.') 257*9c5db199SXin Li event_count = event_count + 1 258*9c5db199SXin Li except TIMEOUT as e: 259*9c5db199SXin Li child_result_list.append(child.before) 260*9c5db199SXin Li break 261*9c5db199SXin Li except EOF as e: 262*9c5db199SXin Li child_result_list.append(child.before) 263*9c5db199SXin Li break 264*9c5db199SXin Li child_result = ''.join(child_result_list) 265*9c5db199SXin Li if withexitstatus: 266*9c5db199SXin Li child.close() 267*9c5db199SXin Li return (child_result, child.exitstatus) 268*9c5db199SXin Li else: 269*9c5db199SXin Li return child_result 270*9c5db199SXin Li 271*9c5db199SXin Liclass spawn (object): 272*9c5db199SXin Li 273*9c5db199SXin Li """This is the main class interface for Pexpect. Use this class to start 274*9c5db199SXin Li and control child applications. """ 275*9c5db199SXin Li 276*9c5db199SXin Li def __init__(self, command, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None): 277*9c5db199SXin Li 278*9c5db199SXin Li """This is the constructor. The command parameter may be a string that 279*9c5db199SXin Li includes a command and any arguments to the command. For example:: 280*9c5db199SXin Li 281*9c5db199SXin Li child = pexpect.spawn ('/usr/bin/ftp') 282*9c5db199SXin Li child = pexpect.spawn ('/usr/bin/ssh [email protected]') 283*9c5db199SXin Li child = pexpect.spawn ('ls -latr /tmp') 284*9c5db199SXin Li 285*9c5db199SXin Li You may also construct it with a list of arguments like so:: 286*9c5db199SXin Li 287*9c5db199SXin Li child = pexpect.spawn ('/usr/bin/ftp', []) 288*9c5db199SXin Li child = pexpect.spawn ('/usr/bin/ssh', ['[email protected]']) 289*9c5db199SXin Li child = pexpect.spawn ('ls', ['-latr', '/tmp']) 290*9c5db199SXin Li 291*9c5db199SXin Li After this the child application will be created and will be ready to 292*9c5db199SXin Li talk to. For normal use, see expect() and send() and sendline(). 293*9c5db199SXin Li 294*9c5db199SXin Li Remember that Pexpect does NOT interpret shell meta characters such as 295*9c5db199SXin Li redirect, pipe, or wild cards (>, |, or *). This is a common mistake. 296*9c5db199SXin Li If you want to run a command and pipe it through another command then 297*9c5db199SXin Li you must also start a shell. For example:: 298*9c5db199SXin Li 299*9c5db199SXin Li child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > log_list.txt"') 300*9c5db199SXin Li child.expect(pexpect.EOF) 301*9c5db199SXin Li 302*9c5db199SXin Li The second form of spawn (where you pass a list of arguments) is useful 303*9c5db199SXin Li in situations where you wish to spawn a command and pass it its own 304*9c5db199SXin Li argument list. This can make syntax more clear. For example, the 305*9c5db199SXin Li following is equivalent to the previous example:: 306*9c5db199SXin Li 307*9c5db199SXin Li shell_cmd = 'ls -l | grep LOG > log_list.txt' 308*9c5db199SXin Li child = pexpect.spawn('/bin/bash', ['-c', shell_cmd]) 309*9c5db199SXin Li child.expect(pexpect.EOF) 310*9c5db199SXin Li 311*9c5db199SXin Li The maxread attribute sets the read buffer size. This is maximum number 312*9c5db199SXin Li of bytes that Pexpect will try to read from a TTY at one time. Setting 313*9c5db199SXin Li the maxread size to 1 will turn off buffering. Setting the maxread 314*9c5db199SXin Li value higher may help performance in cases where large amounts of 315*9c5db199SXin Li output are read back from the child. This feature is useful in 316*9c5db199SXin Li conjunction with searchwindowsize. 317*9c5db199SXin Li 318*9c5db199SXin Li The searchwindowsize attribute sets the how far back in the incomming 319*9c5db199SXin Li seach buffer Pexpect will search for pattern matches. Every time 320*9c5db199SXin Li Pexpect reads some data from the child it will append the data to the 321*9c5db199SXin Li incomming buffer. The default is to search from the beginning of the 322*9c5db199SXin Li imcomming buffer each time new data is read from the child. But this is 323*9c5db199SXin Li very inefficient if you are running a command that generates a large 324*9c5db199SXin Li amount of data where you want to match The searchwindowsize does not 325*9c5db199SXin Li effect the size of the incomming data buffer. You will still have 326*9c5db199SXin Li access to the full buffer after expect() returns. 327*9c5db199SXin Li 328*9c5db199SXin Li The logfile member turns on or off logging. All input and output will 329*9c5db199SXin Li be copied to the given file object. Set logfile to None to stop 330*9c5db199SXin Li logging. This is the default. Set logfile to sys.stdout to echo 331*9c5db199SXin Li everything to standard output. The logfile is flushed after each write. 332*9c5db199SXin Li 333*9c5db199SXin Li Example log input and output to a file:: 334*9c5db199SXin Li 335*9c5db199SXin Li child = pexpect.spawn('some_command') 336*9c5db199SXin Li fout = file('mylog.txt','w') 337*9c5db199SXin Li child.logfile = fout 338*9c5db199SXin Li 339*9c5db199SXin Li Example log to stdout:: 340*9c5db199SXin Li 341*9c5db199SXin Li child = pexpect.spawn('some_command') 342*9c5db199SXin Li child.logfile = sys.stdout 343*9c5db199SXin Li 344*9c5db199SXin Li The logfile_read and logfile_send members can be used to separately log 345*9c5db199SXin Li the input from the child and output sent to the child. Sometimes you 346*9c5db199SXin Li don't want to see everything you write to the child. You only want to 347*9c5db199SXin Li log what the child sends back. For example:: 348*9c5db199SXin Li 349*9c5db199SXin Li child = pexpect.spawn('some_command') 350*9c5db199SXin Li child.logfile_read = sys.stdout 351*9c5db199SXin Li 352*9c5db199SXin Li To separately log output sent to the child use logfile_send:: 353*9c5db199SXin Li 354*9c5db199SXin Li self.logfile_send = fout 355*9c5db199SXin Li 356*9c5db199SXin Li The delaybeforesend helps overcome a weird behavior that many users 357*9c5db199SXin Li were experiencing. The typical problem was that a user would expect() a 358*9c5db199SXin Li "Password:" prompt and then immediately call sendline() to send the 359*9c5db199SXin Li password. The user would then see that their password was echoed back 360*9c5db199SXin Li to them. Passwords don't normally echo. The problem is caused by the 361*9c5db199SXin Li fact that most applications print out the "Password" prompt and then 362*9c5db199SXin Li turn off stdin echo, but if you send your password before the 363*9c5db199SXin Li application turned off echo, then you get your password echoed. 364*9c5db199SXin Li Normally this wouldn't be a problem when interacting with a human at a 365*9c5db199SXin Li real keyboard. If you introduce a slight delay just before writing then 366*9c5db199SXin Li this seems to clear up the problem. This was such a common problem for 367*9c5db199SXin Li many users that I decided that the default pexpect behavior should be 368*9c5db199SXin Li to sleep just before writing to the child application. 1/20th of a 369*9c5db199SXin Li second (50 ms) seems to be enough to clear up the problem. You can set 370*9c5db199SXin Li delaybeforesend to 0 to return to the old behavior. Most Linux machines 371*9c5db199SXin Li don't like this to be below 0.03. I don't know why. 372*9c5db199SXin Li 373*9c5db199SXin Li Note that spawn is clever about finding commands on your path. 374*9c5db199SXin Li It uses the same logic that "which" uses to find executables. 375*9c5db199SXin Li 376*9c5db199SXin Li If you wish to get the exit status of the child you must call the 377*9c5db199SXin Li close() method. The exit or signal status of the child will be stored 378*9c5db199SXin Li in self.exitstatus or self.signalstatus. If the child exited normally 379*9c5db199SXin Li then exitstatus will store the exit return code and signalstatus will 380*9c5db199SXin Li be None. If the child was terminated abnormally with a signal then 381*9c5db199SXin Li signalstatus will store the signal value and exitstatus will be None. 382*9c5db199SXin Li If you need more detail you can also read the self.status member which 383*9c5db199SXin Li stores the status returned by os.waitpid. You can interpret this using 384*9c5db199SXin Li os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG. """ 385*9c5db199SXin Li 386*9c5db199SXin Li self.STDIN_FILENO = pty.STDIN_FILENO 387*9c5db199SXin Li self.STDOUT_FILENO = pty.STDOUT_FILENO 388*9c5db199SXin Li self.STDERR_FILENO = pty.STDERR_FILENO 389*9c5db199SXin Li self.stdin = sys.stdin 390*9c5db199SXin Li self.stdout = sys.stdout 391*9c5db199SXin Li self.stderr = sys.stderr 392*9c5db199SXin Li 393*9c5db199SXin Li self.searcher = None 394*9c5db199SXin Li self.ignorecase = False 395*9c5db199SXin Li self.before = None 396*9c5db199SXin Li self.after = None 397*9c5db199SXin Li self.match = None 398*9c5db199SXin Li self.match_index = None 399*9c5db199SXin Li self.terminated = True 400*9c5db199SXin Li self.exitstatus = None 401*9c5db199SXin Li self.signalstatus = None 402*9c5db199SXin Li self.status = None # status returned by os.waitpid 403*9c5db199SXin Li self.flag_eof = False 404*9c5db199SXin Li self.pid = None 405*9c5db199SXin Li self.child_fd = -1 # initially closed 406*9c5db199SXin Li self.timeout = timeout 407*9c5db199SXin Li self.delimiter = EOF 408*9c5db199SXin Li self.logfile = logfile 409*9c5db199SXin Li self.logfile_read = None # input from child (read_nonblocking) 410*9c5db199SXin Li self.logfile_send = None # output to send (send, sendline) 411*9c5db199SXin Li self.maxread = maxread # max bytes to read at one time into buffer 412*9c5db199SXin Li self.buffer = '' # This is the read buffer. See maxread. 413*9c5db199SXin Li self.searchwindowsize = searchwindowsize # Anything before searchwindowsize point is preserved, but not searched. 414*9c5db199SXin Li # Most Linux machines don't like delaybeforesend to be below 0.03 (30 ms). 415*9c5db199SXin Li self.delaybeforesend = 0.05 # Sets sleep time used just before sending data to child. Time in seconds. 416*9c5db199SXin Li self.delayafterclose = 0.1 # Sets delay in close() method to allow kernel time to update process status. Time in seconds. 417*9c5db199SXin Li self.delayafterterminate = 0.1 # Sets delay in terminate() method to allow kernel time to update process status. Time in seconds. 418*9c5db199SXin Li self.softspace = False # File-like object. 419*9c5db199SXin Li self.name = '<' + repr(self) + '>' # File-like object. 420*9c5db199SXin Li self.encoding = None # File-like object. 421*9c5db199SXin Li self.closed = True # File-like object. 422*9c5db199SXin Li self.cwd = cwd 423*9c5db199SXin Li self.env = env 424*9c5db199SXin Li self.__irix_hack = (sys.platform.lower().find('irix')>=0) # This flags if we are running on irix 425*9c5db199SXin Li # Solaris uses internal __fork_pty(). All others use pty.fork(). 426*9c5db199SXin Li if (sys.platform.lower().find('solaris')>=0) or (sys.platform.lower().find('sunos5')>=0): 427*9c5db199SXin Li self.use_native_pty_fork = False 428*9c5db199SXin Li else: 429*9c5db199SXin Li self.use_native_pty_fork = True 430*9c5db199SXin Li 431*9c5db199SXin Li 432*9c5db199SXin Li # allow stub instances for subclasses that may not use command or args. 433*9c5db199SXin Li if command is None: 434*9c5db199SXin Li self.command = None 435*9c5db199SXin Li self.args = None 436*9c5db199SXin Li self.name = '<pexpect factory incomplete>' 437*9c5db199SXin Li else: 438*9c5db199SXin Li self._spawn (command, args) 439*9c5db199SXin Li 440*9c5db199SXin Li def __del__(self): 441*9c5db199SXin Li 442*9c5db199SXin Li """This makes sure that no system resources are left open. Python only 443*9c5db199SXin Li garbage collects Python objects. OS file descriptors are not Python 444*9c5db199SXin Li objects, so they must be handled explicitly. If the child file 445*9c5db199SXin Li descriptor was opened outside of this class (passed to the constructor) 446*9c5db199SXin Li then this does not close it. """ 447*9c5db199SXin Li 448*9c5db199SXin Li if not self.closed: 449*9c5db199SXin Li # It is possible for __del__ methods to execute during the 450*9c5db199SXin Li # teardown of the Python VM itself. Thus self.close() may 451*9c5db199SXin Li # trigger an exception because os.close may be None. 452*9c5db199SXin Li # -- Fernando Perez 453*9c5db199SXin Li try: 454*9c5db199SXin Li self.close() 455*9c5db199SXin Li except AttributeError: 456*9c5db199SXin Li pass 457*9c5db199SXin Li 458*9c5db199SXin Li def __str__(self): 459*9c5db199SXin Li 460*9c5db199SXin Li """This returns a human-readable string that represents the state of 461*9c5db199SXin Li the object. """ 462*9c5db199SXin Li 463*9c5db199SXin Li s = [] 464*9c5db199SXin Li s.append(repr(self)) 465*9c5db199SXin Li s.append('version: ' + __version__ + ' (' + __revision__ + ')') 466*9c5db199SXin Li s.append('command: ' + str(self.command)) 467*9c5db199SXin Li s.append('args: ' + str(self.args)) 468*9c5db199SXin Li s.append('searcher: ' + str(self.searcher)) 469*9c5db199SXin Li s.append('buffer (last 100 chars): ' + str(self.buffer)[-100:]) 470*9c5db199SXin Li s.append('before (last 100 chars): ' + str(self.before)[-100:]) 471*9c5db199SXin Li s.append('after: ' + str(self.after)) 472*9c5db199SXin Li s.append('match: ' + str(self.match)) 473*9c5db199SXin Li s.append('match_index: ' + str(self.match_index)) 474*9c5db199SXin Li s.append('exitstatus: ' + str(self.exitstatus)) 475*9c5db199SXin Li s.append('flag_eof: ' + str(self.flag_eof)) 476*9c5db199SXin Li s.append('pid: ' + str(self.pid)) 477*9c5db199SXin Li s.append('child_fd: ' + str(self.child_fd)) 478*9c5db199SXin Li s.append('closed: ' + str(self.closed)) 479*9c5db199SXin Li s.append('timeout: ' + str(self.timeout)) 480*9c5db199SXin Li s.append('delimiter: ' + str(self.delimiter)) 481*9c5db199SXin Li s.append('logfile: ' + str(self.logfile)) 482*9c5db199SXin Li s.append('logfile_read: ' + str(self.logfile_read)) 483*9c5db199SXin Li s.append('logfile_send: ' + str(self.logfile_send)) 484*9c5db199SXin Li s.append('maxread: ' + str(self.maxread)) 485*9c5db199SXin Li s.append('ignorecase: ' + str(self.ignorecase)) 486*9c5db199SXin Li s.append('searchwindowsize: ' + str(self.searchwindowsize)) 487*9c5db199SXin Li s.append('delaybeforesend: ' + str(self.delaybeforesend)) 488*9c5db199SXin Li s.append('delayafterclose: ' + str(self.delayafterclose)) 489*9c5db199SXin Li s.append('delayafterterminate: ' + str(self.delayafterterminate)) 490*9c5db199SXin Li return '\n'.join(s) 491*9c5db199SXin Li 492*9c5db199SXin Li def _spawn(self,command,args=[]): 493*9c5db199SXin Li 494*9c5db199SXin Li """This starts the given command in a child process. This does all the 495*9c5db199SXin Li fork/exec type of stuff for a pty. This is called by __init__. If args 496*9c5db199SXin Li is empty then command will be parsed (split on spaces) and args will be 497*9c5db199SXin Li set to parsed arguments. """ 498*9c5db199SXin Li 499*9c5db199SXin Li # The pid and child_fd of this object get set by this method. 500*9c5db199SXin Li # Note that it is difficult for this method to fail. 501*9c5db199SXin Li # You cannot detect if the child process cannot start. 502*9c5db199SXin Li # So the only way you can tell if the child process started 503*9c5db199SXin Li # or not is to try to read from the file descriptor. If you get 504*9c5db199SXin Li # EOF immediately then it means that the child is already dead. 505*9c5db199SXin Li # That may not necessarily be bad because you may haved spawned a child 506*9c5db199SXin Li # that performs some task; creates no stdout output; and then dies. 507*9c5db199SXin Li 508*9c5db199SXin Li # If command is an int type then it may represent a file descriptor. 509*9c5db199SXin Li if type(command) == type(0): 510*9c5db199SXin Li raise ExceptionPexpect ('Command is an int type. If this is a file descriptor then maybe you want to use fdpexpect.fdspawn which takes an existing file descriptor instead of a command string.') 511*9c5db199SXin Li 512*9c5db199SXin Li if type (args) != type([]): 513*9c5db199SXin Li raise TypeError ('The argument, args, must be a list.') 514*9c5db199SXin Li 515*9c5db199SXin Li if args == []: 516*9c5db199SXin Li self.args = split_command_line(command) 517*9c5db199SXin Li self.command = self.args[0] 518*9c5db199SXin Li else: 519*9c5db199SXin Li self.args = args[:] # work with a copy 520*9c5db199SXin Li self.args.insert (0, command) 521*9c5db199SXin Li self.command = command 522*9c5db199SXin Li 523*9c5db199SXin Li command_with_path = which(self.command) 524*9c5db199SXin Li if command_with_path is None: 525*9c5db199SXin Li raise ExceptionPexpect ('The command was not found or was not executable: %s.' % self.command) 526*9c5db199SXin Li self.command = command_with_path 527*9c5db199SXin Li self.args[0] = self.command 528*9c5db199SXin Li 529*9c5db199SXin Li self.name = '<' + ' '.join (self.args) + '>' 530*9c5db199SXin Li 531*9c5db199SXin Li assert self.pid is None, 'The pid member should be None.' 532*9c5db199SXin Li assert self.command is not None, 'The command member should not be None.' 533*9c5db199SXin Li 534*9c5db199SXin Li if self.use_native_pty_fork: 535*9c5db199SXin Li try: 536*9c5db199SXin Li self.pid, self.child_fd = pty.fork() 537*9c5db199SXin Li except OSError as e: 538*9c5db199SXin Li raise ExceptionPexpect('Error! pty.fork() failed: ' + str(e)) 539*9c5db199SXin Li else: # Use internal __fork_pty 540*9c5db199SXin Li self.pid, self.child_fd = self.__fork_pty() 541*9c5db199SXin Li 542*9c5db199SXin Li if self.pid == 0: # Child 543*9c5db199SXin Li try: 544*9c5db199SXin Li self.child_fd = sys.stdout.fileno() # used by setwinsize() 545*9c5db199SXin Li self.setwinsize(24, 80) 546*9c5db199SXin Li except: 547*9c5db199SXin Li # Some platforms do not like setwinsize (Cygwin). 548*9c5db199SXin Li # This will cause problem when running applications that 549*9c5db199SXin Li # are very picky about window size. 550*9c5db199SXin Li # This is a serious limitation, but not a show stopper. 551*9c5db199SXin Li pass 552*9c5db199SXin Li # Do not allow child to inherit open file descriptors from parent. 553*9c5db199SXin Li max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0] 554*9c5db199SXin Li for i in range (3, max_fd): 555*9c5db199SXin Li try: 556*9c5db199SXin Li os.close (i) 557*9c5db199SXin Li except OSError: 558*9c5db199SXin Li pass 559*9c5db199SXin Li 560*9c5db199SXin Li # I don't know why this works, but ignoring SIGHUP fixes a 561*9c5db199SXin Li # problem when trying to start a Java daemon with sudo 562*9c5db199SXin Li # (specifically, Tomcat). 563*9c5db199SXin Li signal.signal(signal.SIGHUP, signal.SIG_IGN) 564*9c5db199SXin Li 565*9c5db199SXin Li if self.cwd is not None: 566*9c5db199SXin Li os.chdir(self.cwd) 567*9c5db199SXin Li if self.env is None: 568*9c5db199SXin Li os.execv(self.command, self.args) 569*9c5db199SXin Li else: 570*9c5db199SXin Li os.execvpe(self.command, self.args, self.env) 571*9c5db199SXin Li 572*9c5db199SXin Li # Parent 573*9c5db199SXin Li self.terminated = False 574*9c5db199SXin Li self.closed = False 575*9c5db199SXin Li 576*9c5db199SXin Li def __fork_pty(self): 577*9c5db199SXin Li 578*9c5db199SXin Li """This implements a substitute for the forkpty system call. This 579*9c5db199SXin Li should be more portable than the pty.fork() function. Specifically, 580*9c5db199SXin Li this should work on Solaris. 581*9c5db199SXin Li 582*9c5db199SXin Li Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to 583*9c5db199SXin Li resolve the issue with Python's pty.fork() not supporting Solaris, 584*9c5db199SXin Li particularly ssh. Based on patch to posixmodule.c authored by Noah 585*9c5db199SXin Li Spurrier:: 586*9c5db199SXin Li 587*9c5db199SXin Li http://mail.python.org/pipermail/python-dev/2003-May/035281.html 588*9c5db199SXin Li 589*9c5db199SXin Li """ 590*9c5db199SXin Li 591*9c5db199SXin Li parent_fd, child_fd = os.openpty() 592*9c5db199SXin Li if parent_fd < 0 or child_fd < 0: 593*9c5db199SXin Li raise ExceptionPexpect("Error! Could not open pty with os.openpty().") 594*9c5db199SXin Li 595*9c5db199SXin Li pid = os.fork() 596*9c5db199SXin Li if pid < 0: 597*9c5db199SXin Li raise ExceptionPexpect("Error! Failed os.fork().") 598*9c5db199SXin Li elif pid == 0: 599*9c5db199SXin Li # Child. 600*9c5db199SXin Li os.close(parent_fd) 601*9c5db199SXin Li self.__pty_make_controlling_tty(child_fd) 602*9c5db199SXin Li 603*9c5db199SXin Li os.dup2(child_fd, 0) 604*9c5db199SXin Li os.dup2(child_fd, 1) 605*9c5db199SXin Li os.dup2(child_fd, 2) 606*9c5db199SXin Li 607*9c5db199SXin Li if child_fd > 2: 608*9c5db199SXin Li os.close(child_fd) 609*9c5db199SXin Li else: 610*9c5db199SXin Li # Parent. 611*9c5db199SXin Li os.close(child_fd) 612*9c5db199SXin Li 613*9c5db199SXin Li return pid, parent_fd 614*9c5db199SXin Li 615*9c5db199SXin Li def __pty_make_controlling_tty(self, tty_fd): 616*9c5db199SXin Li 617*9c5db199SXin Li """This makes the pseudo-terminal the controlling tty. This should be 618*9c5db199SXin Li more portable than the pty.fork() function. Specifically, this should 619*9c5db199SXin Li work on Solaris. """ 620*9c5db199SXin Li 621*9c5db199SXin Li child_name = os.ttyname(tty_fd) 622*9c5db199SXin Li 623*9c5db199SXin Li # Disconnect from controlling tty if still connected. 624*9c5db199SXin Li fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); 625*9c5db199SXin Li if fd >= 0: 626*9c5db199SXin Li os.close(fd) 627*9c5db199SXin Li 628*9c5db199SXin Li os.setsid() 629*9c5db199SXin Li 630*9c5db199SXin Li # Verify we are disconnected from controlling tty 631*9c5db199SXin Li try: 632*9c5db199SXin Li fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY); 633*9c5db199SXin Li if fd >= 0: 634*9c5db199SXin Li os.close(fd) 635*9c5db199SXin Li raise ExceptionPexpect("Error! We are not disconnected from a controlling tty.") 636*9c5db199SXin Li except: 637*9c5db199SXin Li # Good! We are disconnected from a controlling tty. 638*9c5db199SXin Li pass 639*9c5db199SXin Li 640*9c5db199SXin Li # Verify we can open child pty. 641*9c5db199SXin Li fd = os.open(child_name, os.O_RDWR); 642*9c5db199SXin Li if fd < 0: 643*9c5db199SXin Li raise ExceptionPexpect("Error! Could not open child pty, " + child_name) 644*9c5db199SXin Li else: 645*9c5db199SXin Li os.close(fd) 646*9c5db199SXin Li 647*9c5db199SXin Li # Verify we now have a controlling tty. 648*9c5db199SXin Li fd = os.open("/dev/tty", os.O_WRONLY) 649*9c5db199SXin Li if fd < 0: 650*9c5db199SXin Li raise ExceptionPexpect("Error! Could not open controlling tty, /dev/tty") 651*9c5db199SXin Li else: 652*9c5db199SXin Li os.close(fd) 653*9c5db199SXin Li 654*9c5db199SXin Li def fileno (self): # File-like object. 655*9c5db199SXin Li 656*9c5db199SXin Li """This returns the file descriptor of the pty for the child. 657*9c5db199SXin Li """ 658*9c5db199SXin Li 659*9c5db199SXin Li return self.child_fd 660*9c5db199SXin Li 661*9c5db199SXin Li def close (self, force=True): # File-like object. 662*9c5db199SXin Li 663*9c5db199SXin Li """This closes the connection with the child application. Note that 664*9c5db199SXin Li calling close() more than once is valid. This emulates standard Python 665*9c5db199SXin Li behavior with files. Set force to True if you want to make sure that 666*9c5db199SXin Li the child is terminated (SIGKILL is sent if the child ignores SIGHUP 667*9c5db199SXin Li and SIGINT). """ 668*9c5db199SXin Li 669*9c5db199SXin Li if not self.closed: 670*9c5db199SXin Li self.flush() 671*9c5db199SXin Li os.close (self.child_fd) 672*9c5db199SXin Li time.sleep(self.delayafterclose) # Give kernel time to update process status. 673*9c5db199SXin Li if self.isalive(): 674*9c5db199SXin Li if not self.terminate(force): 675*9c5db199SXin Li raise ExceptionPexpect('close() could not terminate the child using terminate()') 676*9c5db199SXin Li self.child_fd = -1 677*9c5db199SXin Li self.closed = True 678*9c5db199SXin Li #self.pid = None 679*9c5db199SXin Li 680*9c5db199SXin Li def flush (self): # File-like object. 681*9c5db199SXin Li 682*9c5db199SXin Li """This does nothing. It is here to support the interface for a 683*9c5db199SXin Li File-like object. """ 684*9c5db199SXin Li 685*9c5db199SXin Li pass 686*9c5db199SXin Li 687*9c5db199SXin Li def isatty (self): # File-like object. 688*9c5db199SXin Li 689*9c5db199SXin Li """This returns True if the file descriptor is open and connected to a 690*9c5db199SXin Li tty(-like) device, else False. """ 691*9c5db199SXin Li 692*9c5db199SXin Li return os.isatty(self.child_fd) 693*9c5db199SXin Li 694*9c5db199SXin Li def waitnoecho (self, timeout=-1): 695*9c5db199SXin Li 696*9c5db199SXin Li """This waits until the terminal ECHO flag is set False. This returns 697*9c5db199SXin Li True if the echo mode is off. This returns False if the ECHO flag was 698*9c5db199SXin Li not set False before the timeout. This can be used to detect when the 699*9c5db199SXin Li child is waiting for a password. Usually a child application will turn 700*9c5db199SXin Li off echo mode when it is waiting for the user to enter a password. For 701*9c5db199SXin Li example, instead of expecting the "password:" prompt you can wait for 702*9c5db199SXin Li the child to set ECHO off:: 703*9c5db199SXin Li 704*9c5db199SXin Li p = pexpect.spawn ('ssh [email protected]') 705*9c5db199SXin Li p.waitnoecho() 706*9c5db199SXin Li p.sendline(mypassword) 707*9c5db199SXin Li 708*9c5db199SXin Li If timeout is None then this method to block forever until ECHO flag is 709*9c5db199SXin Li False. 710*9c5db199SXin Li 711*9c5db199SXin Li """ 712*9c5db199SXin Li 713*9c5db199SXin Li if timeout == -1: 714*9c5db199SXin Li timeout = self.timeout 715*9c5db199SXin Li if timeout is not None: 716*9c5db199SXin Li end_time = time.time() + timeout 717*9c5db199SXin Li while True: 718*9c5db199SXin Li if not self.getecho(): 719*9c5db199SXin Li return True 720*9c5db199SXin Li if timeout < 0 and timeout is not None: 721*9c5db199SXin Li return False 722*9c5db199SXin Li if timeout is not None: 723*9c5db199SXin Li timeout = end_time - time.time() 724*9c5db199SXin Li time.sleep(0.1) 725*9c5db199SXin Li 726*9c5db199SXin Li def getecho (self): 727*9c5db199SXin Li 728*9c5db199SXin Li """This returns the terminal echo mode. This returns True if echo is 729*9c5db199SXin Li on or False if echo is off. Child applications that are expecting you 730*9c5db199SXin Li to enter a password often set ECHO False. See waitnoecho(). """ 731*9c5db199SXin Li 732*9c5db199SXin Li attr = termios.tcgetattr(self.child_fd) 733*9c5db199SXin Li if attr[3] & termios.ECHO: 734*9c5db199SXin Li return True 735*9c5db199SXin Li return False 736*9c5db199SXin Li 737*9c5db199SXin Li def setecho (self, state): 738*9c5db199SXin Li 739*9c5db199SXin Li """This sets the terminal echo mode on or off. Note that anything the 740*9c5db199SXin Li child sent before the echo will be lost, so you should be sure that 741*9c5db199SXin Li your input buffer is empty before you call setecho(). For example, the 742*9c5db199SXin Li following will work as expected:: 743*9c5db199SXin Li 744*9c5db199SXin Li p = pexpect.spawn('cat') 745*9c5db199SXin Li p.sendline ('1234') # We will see this twice (once from tty echo and again from cat). 746*9c5db199SXin Li p.expect (['1234']) 747*9c5db199SXin Li p.expect (['1234']) 748*9c5db199SXin Li p.setecho(False) # Turn off tty echo 749*9c5db199SXin Li p.sendline ('abcd') # We will set this only once (echoed by cat). 750*9c5db199SXin Li p.sendline ('wxyz') # We will set this only once (echoed by cat) 751*9c5db199SXin Li p.expect (['abcd']) 752*9c5db199SXin Li p.expect (['wxyz']) 753*9c5db199SXin Li 754*9c5db199SXin Li The following WILL NOT WORK because the lines sent before the setecho 755*9c5db199SXin Li will be lost:: 756*9c5db199SXin Li 757*9c5db199SXin Li p = pexpect.spawn('cat') 758*9c5db199SXin Li p.sendline ('1234') # We will see this twice (once from tty echo and again from cat). 759*9c5db199SXin Li p.setecho(False) # Turn off tty echo 760*9c5db199SXin Li p.sendline ('abcd') # We will set this only once (echoed by cat). 761*9c5db199SXin Li p.sendline ('wxyz') # We will set this only once (echoed by cat) 762*9c5db199SXin Li p.expect (['1234']) 763*9c5db199SXin Li p.expect (['1234']) 764*9c5db199SXin Li p.expect (['abcd']) 765*9c5db199SXin Li p.expect (['wxyz']) 766*9c5db199SXin Li """ 767*9c5db199SXin Li 768*9c5db199SXin Li self.child_fd 769*9c5db199SXin Li attr = termios.tcgetattr(self.child_fd) 770*9c5db199SXin Li if state: 771*9c5db199SXin Li attr[3] = attr[3] | termios.ECHO 772*9c5db199SXin Li else: 773*9c5db199SXin Li attr[3] = attr[3] & ~termios.ECHO 774*9c5db199SXin Li # I tried TCSADRAIN and TCSAFLUSH, but these were inconsistent 775*9c5db199SXin Li # and blocked on some platforms. TCSADRAIN is probably ideal if it worked. 776*9c5db199SXin Li termios.tcsetattr(self.child_fd, termios.TCSANOW, attr) 777*9c5db199SXin Li 778*9c5db199SXin Li def read_nonblocking (self, size = 1, timeout = -1): 779*9c5db199SXin Li 780*9c5db199SXin Li """This reads at most size characters from the child application. It 781*9c5db199SXin Li includes a timeout. If the read does not complete within the timeout 782*9c5db199SXin Li period then a TIMEOUT exception is raised. If the end of file is read 783*9c5db199SXin Li then an EOF exception will be raised. If a log file was set using 784*9c5db199SXin Li setlog() then all data will also be written to the log file. 785*9c5db199SXin Li 786*9c5db199SXin Li If timeout is None then the read may block indefinitely. If timeout is -1 787*9c5db199SXin Li then the self.timeout value is used. If timeout is 0 then the child is 788*9c5db199SXin Li polled and if there was no data immediately ready then this will raise 789*9c5db199SXin Li a TIMEOUT exception. 790*9c5db199SXin Li 791*9c5db199SXin Li The timeout refers only to the amount of time to read at least one 792*9c5db199SXin Li character. This is not effected by the 'size' parameter, so if you call 793*9c5db199SXin Li read_nonblocking(size=100, timeout=30) and only one character is 794*9c5db199SXin Li available right away then one character will be returned immediately. 795*9c5db199SXin Li It will not wait for 30 seconds for another 99 characters to come in. 796*9c5db199SXin Li 797*9c5db199SXin Li This is a wrapper around os.read(). It uses select.select() to 798*9c5db199SXin Li implement the timeout. """ 799*9c5db199SXin Li 800*9c5db199SXin Li if self.closed: 801*9c5db199SXin Li raise ValueError ('I/O operation on closed file in read_nonblocking().') 802*9c5db199SXin Li 803*9c5db199SXin Li if timeout == -1: 804*9c5db199SXin Li timeout = self.timeout 805*9c5db199SXin Li 806*9c5db199SXin Li # Note that some systems such as Solaris do not give an EOF when 807*9c5db199SXin Li # the child dies. In fact, you can still try to read 808*9c5db199SXin Li # from the child_fd -- it will block forever or until TIMEOUT. 809*9c5db199SXin Li # For this case, I test isalive() before doing any reading. 810*9c5db199SXin Li # If isalive() is false, then I pretend that this is the same as EOF. 811*9c5db199SXin Li if not self.isalive(): 812*9c5db199SXin Li r,w,e = self.__select([self.child_fd], [], [], 0) # timeout of 0 means "poll" 813*9c5db199SXin Li if not r: 814*9c5db199SXin Li self.flag_eof = True 815*9c5db199SXin Li raise EOF ('End Of File (EOF) in read_nonblocking(). Braindead platform.') 816*9c5db199SXin Li elif self.__irix_hack: 817*9c5db199SXin Li # This is a hack for Irix. It seems that Irix requires a long delay before checking isalive. 818*9c5db199SXin Li # This adds a 2 second delay, but only when the child is terminated. 819*9c5db199SXin Li r, w, e = self.__select([self.child_fd], [], [], 2) 820*9c5db199SXin Li if not r and not self.isalive(): 821*9c5db199SXin Li self.flag_eof = True 822*9c5db199SXin Li raise EOF ('End Of File (EOF) in read_nonblocking(). Pokey platform.') 823*9c5db199SXin Li 824*9c5db199SXin Li r,w,e = self.__select([self.child_fd], [], [], timeout) 825*9c5db199SXin Li 826*9c5db199SXin Li if not r: 827*9c5db199SXin Li if not self.isalive(): 828*9c5db199SXin Li # Some platforms, such as Irix, will claim that their processes are alive; 829*9c5db199SXin Li # then timeout on the select; and then finally admit that they are not alive. 830*9c5db199SXin Li self.flag_eof = True 831*9c5db199SXin Li raise EOF ('End of File (EOF) in read_nonblocking(). Very pokey platform.') 832*9c5db199SXin Li else: 833*9c5db199SXin Li raise TIMEOUT ('Timeout exceeded in read_nonblocking().') 834*9c5db199SXin Li 835*9c5db199SXin Li if self.child_fd in r: 836*9c5db199SXin Li try: 837*9c5db199SXin Li s = os.read(self.child_fd, size) 838*9c5db199SXin Li except OSError as e: # Linux does this 839*9c5db199SXin Li self.flag_eof = True 840*9c5db199SXin Li raise EOF ('End Of File (EOF) in read_nonblocking(). Exception style platform.') 841*9c5db199SXin Li if s == '': # BSD style 842*9c5db199SXin Li self.flag_eof = True 843*9c5db199SXin Li raise EOF ('End Of File (EOF) in read_nonblocking(). Empty string style platform.') 844*9c5db199SXin Li 845*9c5db199SXin Li if self.logfile is not None: 846*9c5db199SXin Li self.logfile.write (s) 847*9c5db199SXin Li self.logfile.flush() 848*9c5db199SXin Li if self.logfile_read is not None: 849*9c5db199SXin Li self.logfile_read.write (s) 850*9c5db199SXin Li self.logfile_read.flush() 851*9c5db199SXin Li 852*9c5db199SXin Li return s 853*9c5db199SXin Li 854*9c5db199SXin Li raise ExceptionPexpect ('Reached an unexpected state in read_nonblocking().') 855*9c5db199SXin Li 856*9c5db199SXin Li def read (self, size = -1): # File-like object. 857*9c5db199SXin Li 858*9c5db199SXin Li """This reads at most "size" bytes from the file (less if the read hits 859*9c5db199SXin Li EOF before obtaining size bytes). If the size argument is negative or 860*9c5db199SXin Li omitted, read all data until EOF is reached. The bytes are returned as 861*9c5db199SXin Li a string object. An empty string is returned when EOF is encountered 862*9c5db199SXin Li immediately. """ 863*9c5db199SXin Li 864*9c5db199SXin Li if size == 0: 865*9c5db199SXin Li return '' 866*9c5db199SXin Li if size < 0: 867*9c5db199SXin Li self.expect (self.delimiter) # delimiter default is EOF 868*9c5db199SXin Li return self.before 869*9c5db199SXin Li 870*9c5db199SXin Li # I could have done this more directly by not using expect(), but 871*9c5db199SXin Li # I deliberately decided to couple read() to expect() so that 872*9c5db199SXin Li # I would catch any bugs early and ensure consistant behavior. 873*9c5db199SXin Li # It's a little less efficient, but there is less for me to 874*9c5db199SXin Li # worry about if I have to later modify read() or expect(). 875*9c5db199SXin Li # Note, it's OK if size==-1 in the regex. That just means it 876*9c5db199SXin Li # will never match anything in which case we stop only on EOF. 877*9c5db199SXin Li cre = re.compile('.{%d}' % size, re.DOTALL) 878*9c5db199SXin Li index = self.expect ([cre, self.delimiter]) # delimiter default is EOF 879*9c5db199SXin Li if index == 0: 880*9c5db199SXin Li return self.after ### self.before should be ''. Should I assert this? 881*9c5db199SXin Li return self.before 882*9c5db199SXin Li 883*9c5db199SXin Li def readline (self, size = -1): # File-like object. 884*9c5db199SXin Li 885*9c5db199SXin Li """This reads and returns one entire line. A trailing newline is kept 886*9c5db199SXin Li in the string, but may be absent when a file ends with an incomplete 887*9c5db199SXin Li line. Note: This readline() looks for a \\r\\n pair even on UNIX 888*9c5db199SXin Li because this is what the pseudo tty device returns. So contrary to what 889*9c5db199SXin Li you may expect you will receive the newline as \\r\\n. An empty string 890*9c5db199SXin Li is returned when EOF is hit immediately. Currently, the size argument is 891*9c5db199SXin Li mostly ignored, so this behavior is not standard for a file-like 892*9c5db199SXin Li object. If size is 0 then an empty string is returned. """ 893*9c5db199SXin Li 894*9c5db199SXin Li if size == 0: 895*9c5db199SXin Li return '' 896*9c5db199SXin Li index = self.expect (['\r\n', self.delimiter]) # delimiter default is EOF 897*9c5db199SXin Li if index == 0: 898*9c5db199SXin Li return self.before + '\r\n' 899*9c5db199SXin Li else: 900*9c5db199SXin Li return self.before 901*9c5db199SXin Li 902*9c5db199SXin Li def __iter__ (self): # File-like object. 903*9c5db199SXin Li 904*9c5db199SXin Li """This is to support iterators over a file-like object. 905*9c5db199SXin Li """ 906*9c5db199SXin Li 907*9c5db199SXin Li return self 908*9c5db199SXin Li 909*9c5db199SXin Li def next (self): # File-like object. 910*9c5db199SXin Li 911*9c5db199SXin Li """This is to support iterators over a file-like object. 912*9c5db199SXin Li """ 913*9c5db199SXin Li 914*9c5db199SXin Li result = self.readline() 915*9c5db199SXin Li if result == "": 916*9c5db199SXin Li raise StopIteration 917*9c5db199SXin Li return result 918*9c5db199SXin Li 919*9c5db199SXin Li def readlines (self, sizehint = -1): # File-like object. 920*9c5db199SXin Li 921*9c5db199SXin Li """This reads until EOF using readline() and returns a list containing 922*9c5db199SXin Li the lines thus read. The optional "sizehint" argument is ignored. """ 923*9c5db199SXin Li 924*9c5db199SXin Li lines = [] 925*9c5db199SXin Li while True: 926*9c5db199SXin Li line = self.readline() 927*9c5db199SXin Li if not line: 928*9c5db199SXin Li break 929*9c5db199SXin Li lines.append(line) 930*9c5db199SXin Li return lines 931*9c5db199SXin Li 932*9c5db199SXin Li def write(self, s): # File-like object. 933*9c5db199SXin Li 934*9c5db199SXin Li """This is similar to send() except that there is no return value. 935*9c5db199SXin Li """ 936*9c5db199SXin Li 937*9c5db199SXin Li self.send (s) 938*9c5db199SXin Li 939*9c5db199SXin Li def writelines (self, sequence): # File-like object. 940*9c5db199SXin Li 941*9c5db199SXin Li """This calls write() for each element in the sequence. The sequence 942*9c5db199SXin Li can be any iterable object producing strings, typically a list of 943*9c5db199SXin Li strings. This does not add line separators There is no return value. 944*9c5db199SXin Li """ 945*9c5db199SXin Li 946*9c5db199SXin Li for s in sequence: 947*9c5db199SXin Li self.write (s) 948*9c5db199SXin Li 949*9c5db199SXin Li def send(self, s): 950*9c5db199SXin Li 951*9c5db199SXin Li """This sends a string to the child process. This returns the number of 952*9c5db199SXin Li bytes written. If a log file was set then the data is also written to 953*9c5db199SXin Li the log. """ 954*9c5db199SXin Li 955*9c5db199SXin Li time.sleep(self.delaybeforesend) 956*9c5db199SXin Li if self.logfile is not None: 957*9c5db199SXin Li self.logfile.write (s) 958*9c5db199SXin Li self.logfile.flush() 959*9c5db199SXin Li if self.logfile_send is not None: 960*9c5db199SXin Li self.logfile_send.write (s) 961*9c5db199SXin Li self.logfile_send.flush() 962*9c5db199SXin Li c = os.write(self.child_fd, s) 963*9c5db199SXin Li return c 964*9c5db199SXin Li 965*9c5db199SXin Li def sendline(self, s=''): 966*9c5db199SXin Li 967*9c5db199SXin Li """This is like send(), but it adds a line feed (os.linesep). This 968*9c5db199SXin Li returns the number of bytes written. """ 969*9c5db199SXin Li 970*9c5db199SXin Li n = self.send(s) 971*9c5db199SXin Li n = n + self.send (os.linesep) 972*9c5db199SXin Li return n 973*9c5db199SXin Li 974*9c5db199SXin Li def sendcontrol(self, char): 975*9c5db199SXin Li 976*9c5db199SXin Li """This sends a control character to the child such as Ctrl-C or 977*9c5db199SXin Li Ctrl-D. For example, to send a Ctrl-G (ASCII 7):: 978*9c5db199SXin Li 979*9c5db199SXin Li child.sendcontrol('g') 980*9c5db199SXin Li 981*9c5db199SXin Li See also, sendintr() and sendeof(). 982*9c5db199SXin Li """ 983*9c5db199SXin Li 984*9c5db199SXin Li char = char.lower() 985*9c5db199SXin Li a = ord(char) 986*9c5db199SXin Li if a>=97 and a<=122: 987*9c5db199SXin Li a = a - ord('a') + 1 988*9c5db199SXin Li return self.send (chr(a)) 989*9c5db199SXin Li d = {'@':0, '`':0, 990*9c5db199SXin Li '[':27, '{':27, 991*9c5db199SXin Li '\\':28, '|':28, 992*9c5db199SXin Li ']':29, '}': 29, 993*9c5db199SXin Li '^':30, '~':30, 994*9c5db199SXin Li '_':31, 995*9c5db199SXin Li '?':127} 996*9c5db199SXin Li if char not in d: 997*9c5db199SXin Li return 0 998*9c5db199SXin Li return self.send (chr(d[char])) 999*9c5db199SXin Li 1000*9c5db199SXin Li def sendeof(self): 1001*9c5db199SXin Li 1002*9c5db199SXin Li """This sends an EOF to the child. This sends a character which causes 1003*9c5db199SXin Li the pending parent output buffer to be sent to the waiting child 1004*9c5db199SXin Li program without waiting for end-of-line. If it is the first character 1005*9c5db199SXin Li of the line, the read() in the user program returns 0, which signifies 1006*9c5db199SXin Li end-of-file. This means to work as expected a sendeof() has to be 1007*9c5db199SXin Li called at the beginning of a line. This method does not send a newline. 1008*9c5db199SXin Li It is the responsibility of the caller to ensure the eof is sent at the 1009*9c5db199SXin Li beginning of a line. """ 1010*9c5db199SXin Li 1011*9c5db199SXin Li ### Hmmm... how do I send an EOF? 1012*9c5db199SXin Li ###C if ((m = write(pty, *buf, p - *buf)) < 0) 1013*9c5db199SXin Li ###C return (errno == EWOULDBLOCK) ? n : -1; 1014*9c5db199SXin Li #fd = sys.stdin.fileno() 1015*9c5db199SXin Li #old = termios.tcgetattr(fd) # remember current state 1016*9c5db199SXin Li #attr = termios.tcgetattr(fd) 1017*9c5db199SXin Li #attr[3] = attr[3] | termios.ICANON # ICANON must be set to recognize EOF 1018*9c5db199SXin Li #try: # use try/finally to ensure state gets restored 1019*9c5db199SXin Li # termios.tcsetattr(fd, termios.TCSADRAIN, attr) 1020*9c5db199SXin Li # if hasattr(termios, 'CEOF'): 1021*9c5db199SXin Li # os.write (self.child_fd, '%c' % termios.CEOF) 1022*9c5db199SXin Li # else: 1023*9c5db199SXin Li # # Silly platform does not define CEOF so assume CTRL-D 1024*9c5db199SXin Li # os.write (self.child_fd, '%c' % 4) 1025*9c5db199SXin Li #finally: # restore state 1026*9c5db199SXin Li # termios.tcsetattr(fd, termios.TCSADRAIN, old) 1027*9c5db199SXin Li if hasattr(termios, 'VEOF'): 1028*9c5db199SXin Li char = termios.tcgetattr(self.child_fd)[6][termios.VEOF] 1029*9c5db199SXin Li else: 1030*9c5db199SXin Li # platform does not define VEOF so assume CTRL-D 1031*9c5db199SXin Li char = chr(4) 1032*9c5db199SXin Li self.send(char) 1033*9c5db199SXin Li 1034*9c5db199SXin Li def sendintr(self): 1035*9c5db199SXin Li 1036*9c5db199SXin Li """This sends a SIGINT to the child. It does not require 1037*9c5db199SXin Li the SIGINT to be the first character on a line. """ 1038*9c5db199SXin Li 1039*9c5db199SXin Li if hasattr(termios, 'VINTR'): 1040*9c5db199SXin Li char = termios.tcgetattr(self.child_fd)[6][termios.VINTR] 1041*9c5db199SXin Li else: 1042*9c5db199SXin Li # platform does not define VINTR so assume CTRL-C 1043*9c5db199SXin Li char = chr(3) 1044*9c5db199SXin Li self.send (char) 1045*9c5db199SXin Li 1046*9c5db199SXin Li def eof (self): 1047*9c5db199SXin Li 1048*9c5db199SXin Li """This returns True if the EOF exception was ever raised. 1049*9c5db199SXin Li """ 1050*9c5db199SXin Li 1051*9c5db199SXin Li return self.flag_eof 1052*9c5db199SXin Li 1053*9c5db199SXin Li def terminate(self, force=False): 1054*9c5db199SXin Li 1055*9c5db199SXin Li """This forces a child process to terminate. It starts nicely with 1056*9c5db199SXin Li SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This 1057*9c5db199SXin Li returns True if the child was terminated. This returns False if the 1058*9c5db199SXin Li child could not be terminated. """ 1059*9c5db199SXin Li 1060*9c5db199SXin Li if not self.isalive(): 1061*9c5db199SXin Li return True 1062*9c5db199SXin Li try: 1063*9c5db199SXin Li self.kill(signal.SIGHUP) 1064*9c5db199SXin Li time.sleep(self.delayafterterminate) 1065*9c5db199SXin Li if not self.isalive(): 1066*9c5db199SXin Li return True 1067*9c5db199SXin Li self.kill(signal.SIGCONT) 1068*9c5db199SXin Li time.sleep(self.delayafterterminate) 1069*9c5db199SXin Li if not self.isalive(): 1070*9c5db199SXin Li return True 1071*9c5db199SXin Li self.kill(signal.SIGINT) 1072*9c5db199SXin Li time.sleep(self.delayafterterminate) 1073*9c5db199SXin Li if not self.isalive(): 1074*9c5db199SXin Li return True 1075*9c5db199SXin Li if force: 1076*9c5db199SXin Li self.kill(signal.SIGKILL) 1077*9c5db199SXin Li time.sleep(self.delayafterterminate) 1078*9c5db199SXin Li if not self.isalive(): 1079*9c5db199SXin Li return True 1080*9c5db199SXin Li else: 1081*9c5db199SXin Li return False 1082*9c5db199SXin Li return False 1083*9c5db199SXin Li except OSError as e: 1084*9c5db199SXin Li # I think there are kernel timing issues that sometimes cause 1085*9c5db199SXin Li # this to happen. I think isalive() reports True, but the 1086*9c5db199SXin Li # process is dead to the kernel. 1087*9c5db199SXin Li # Make one last attempt to see if the kernel is up to date. 1088*9c5db199SXin Li time.sleep(self.delayafterterminate) 1089*9c5db199SXin Li if not self.isalive(): 1090*9c5db199SXin Li return True 1091*9c5db199SXin Li else: 1092*9c5db199SXin Li return False 1093*9c5db199SXin Li 1094*9c5db199SXin Li def wait(self): 1095*9c5db199SXin Li 1096*9c5db199SXin Li """This waits until the child exits. This is a blocking call. This will 1097*9c5db199SXin Li not read any data from the child, so this will block forever if the 1098*9c5db199SXin Li child has unread output and has terminated. In other words, the child 1099*9c5db199SXin Li may have printed output then called exit(); but, technically, the child 1100*9c5db199SXin Li is still alive until its output is read. """ 1101*9c5db199SXin Li 1102*9c5db199SXin Li if self.isalive(): 1103*9c5db199SXin Li pid, status = os.waitpid(self.pid, 0) 1104*9c5db199SXin Li else: 1105*9c5db199SXin Li raise ExceptionPexpect ('Cannot wait for dead child process.') 1106*9c5db199SXin Li self.exitstatus = os.WEXITSTATUS(status) 1107*9c5db199SXin Li if os.WIFEXITED (status): 1108*9c5db199SXin Li self.status = status 1109*9c5db199SXin Li self.exitstatus = os.WEXITSTATUS(status) 1110*9c5db199SXin Li self.signalstatus = None 1111*9c5db199SXin Li self.terminated = True 1112*9c5db199SXin Li elif os.WIFSIGNALED (status): 1113*9c5db199SXin Li self.status = status 1114*9c5db199SXin Li self.exitstatus = None 1115*9c5db199SXin Li self.signalstatus = os.WTERMSIG(status) 1116*9c5db199SXin Li self.terminated = True 1117*9c5db199SXin Li elif os.WIFSTOPPED (status): 1118*9c5db199SXin Li raise ExceptionPexpect ('Wait was called for a child process that is stopped. This is not supported. Is some other process attempting job control with our child pid?') 1119*9c5db199SXin Li return self.exitstatus 1120*9c5db199SXin Li 1121*9c5db199SXin Li def isalive(self): 1122*9c5db199SXin Li 1123*9c5db199SXin Li """This tests if the child process is running or not. This is 1124*9c5db199SXin Li non-blocking. If the child was terminated then this will read the 1125*9c5db199SXin Li exitstatus or signalstatus of the child. This returns True if the child 1126*9c5db199SXin Li process appears to be running or False if not. It can take literally 1127*9c5db199SXin Li SECONDS for Solaris to return the right status. """ 1128*9c5db199SXin Li 1129*9c5db199SXin Li if self.terminated: 1130*9c5db199SXin Li return False 1131*9c5db199SXin Li 1132*9c5db199SXin Li if self.flag_eof: 1133*9c5db199SXin Li # This is for Linux, which requires the blocking form of waitpid to get 1134*9c5db199SXin Li # status of a defunct process. This is super-lame. The flag_eof would have 1135*9c5db199SXin Li # been set in read_nonblocking(), so this should be safe. 1136*9c5db199SXin Li waitpid_options = 0 1137*9c5db199SXin Li else: 1138*9c5db199SXin Li waitpid_options = os.WNOHANG 1139*9c5db199SXin Li 1140*9c5db199SXin Li try: 1141*9c5db199SXin Li pid, status = os.waitpid(self.pid, waitpid_options) 1142*9c5db199SXin Li except OSError as e: # No child processes 1143*9c5db199SXin Li if e[0] == errno.ECHILD: 1144*9c5db199SXin Li raise ExceptionPexpect ('isalive() encountered condition where "terminated" is 0, but there was no child process. Did someone else call waitpid() on our process?') 1145*9c5db199SXin Li else: 1146*9c5db199SXin Li raise e 1147*9c5db199SXin Li 1148*9c5db199SXin Li # I have to do this twice for Solaris. I can't even believe that I figured this out... 1149*9c5db199SXin Li # If waitpid() returns 0 it means that no child process wishes to 1150*9c5db199SXin Li # report, and the value of status is undefined. 1151*9c5db199SXin Li if pid == 0: 1152*9c5db199SXin Li try: 1153*9c5db199SXin Li pid, status = os.waitpid(self.pid, waitpid_options) ### os.WNOHANG) # Solaris! 1154*9c5db199SXin Li except OSError as e: # This should never happen... 1155*9c5db199SXin Li if e[0] == errno.ECHILD: 1156*9c5db199SXin Li raise ExceptionPexpect ('isalive() encountered condition that should never happen. There was no child process. Did someone else call waitpid() on our process?') 1157*9c5db199SXin Li else: 1158*9c5db199SXin Li raise e 1159*9c5db199SXin Li 1160*9c5db199SXin Li # If pid is still 0 after two calls to waitpid() then 1161*9c5db199SXin Li # the process really is alive. This seems to work on all platforms, except 1162*9c5db199SXin Li # for Irix which seems to require a blocking call on waitpid or select, so I let read_nonblocking 1163*9c5db199SXin Li # take care of this situation (unfortunately, this requires waiting through the timeout). 1164*9c5db199SXin Li if pid == 0: 1165*9c5db199SXin Li return True 1166*9c5db199SXin Li 1167*9c5db199SXin Li if pid == 0: 1168*9c5db199SXin Li return True 1169*9c5db199SXin Li 1170*9c5db199SXin Li if os.WIFEXITED (status): 1171*9c5db199SXin Li self.status = status 1172*9c5db199SXin Li self.exitstatus = os.WEXITSTATUS(status) 1173*9c5db199SXin Li self.signalstatus = None 1174*9c5db199SXin Li self.terminated = True 1175*9c5db199SXin Li elif os.WIFSIGNALED (status): 1176*9c5db199SXin Li self.status = status 1177*9c5db199SXin Li self.exitstatus = None 1178*9c5db199SXin Li self.signalstatus = os.WTERMSIG(status) 1179*9c5db199SXin Li self.terminated = True 1180*9c5db199SXin Li elif os.WIFSTOPPED (status): 1181*9c5db199SXin Li raise ExceptionPexpect ('isalive() encountered condition where child process is stopped. This is not supported. Is some other process attempting job control with our child pid?') 1182*9c5db199SXin Li return False 1183*9c5db199SXin Li 1184*9c5db199SXin Li def kill(self, sig): 1185*9c5db199SXin Li 1186*9c5db199SXin Li """This sends the given signal to the child application. In keeping 1187*9c5db199SXin Li with UNIX tradition it has a misleading name. It does not necessarily 1188*9c5db199SXin Li kill the child unless you send the right signal. """ 1189*9c5db199SXin Li 1190*9c5db199SXin Li # Same as os.kill, but the pid is given for you. 1191*9c5db199SXin Li if self.isalive(): 1192*9c5db199SXin Li os.kill(self.pid, sig) 1193*9c5db199SXin Li 1194*9c5db199SXin Li def compile_pattern_list(self, patterns): 1195*9c5db199SXin Li 1196*9c5db199SXin Li """This compiles a pattern-string or a list of pattern-strings. 1197*9c5db199SXin Li Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of 1198*9c5db199SXin Li those. Patterns may also be None which results in an empty list (you 1199*9c5db199SXin Li might do this if waiting for an EOF or TIMEOUT condition without 1200*9c5db199SXin Li expecting any pattern). 1201*9c5db199SXin Li 1202*9c5db199SXin Li This is used by expect() when calling expect_list(). Thus expect() is 1203*9c5db199SXin Li nothing more than:: 1204*9c5db199SXin Li 1205*9c5db199SXin Li cpl = self.compile_pattern_list(pl) 1206*9c5db199SXin Li return self.expect_list(cpl, timeout) 1207*9c5db199SXin Li 1208*9c5db199SXin Li If you are using expect() within a loop it may be more 1209*9c5db199SXin Li efficient to compile the patterns first and then call expect_list(). 1210*9c5db199SXin Li This avoid calls in a loop to compile_pattern_list():: 1211*9c5db199SXin Li 1212*9c5db199SXin Li cpl = self.compile_pattern_list(my_pattern) 1213*9c5db199SXin Li while some_condition: 1214*9c5db199SXin Li ... 1215*9c5db199SXin Li i = self.expect_list(clp, timeout) 1216*9c5db199SXin Li ... 1217*9c5db199SXin Li """ 1218*9c5db199SXin Li 1219*9c5db199SXin Li if patterns is None: 1220*9c5db199SXin Li return [] 1221*9c5db199SXin Li if type(patterns) is not list: 1222*9c5db199SXin Li patterns = [patterns] 1223*9c5db199SXin Li 1224*9c5db199SXin Li compile_flags = re.DOTALL # Allow dot to match \n 1225*9c5db199SXin Li if self.ignorecase: 1226*9c5db199SXin Li compile_flags = compile_flags | re.IGNORECASE 1227*9c5db199SXin Li compiled_pattern_list = [] 1228*9c5db199SXin Li for p in patterns: 1229*9c5db199SXin Li if isinstance(p, six.string_types): 1230*9c5db199SXin Li compiled_pattern_list.append(re.compile(p, compile_flags)) 1231*9c5db199SXin Li elif p is EOF: 1232*9c5db199SXin Li compiled_pattern_list.append(EOF) 1233*9c5db199SXin Li elif p is TIMEOUT: 1234*9c5db199SXin Li compiled_pattern_list.append(TIMEOUT) 1235*9c5db199SXin Li elif type(p) is type(re.compile('')): 1236*9c5db199SXin Li compiled_pattern_list.append(p) 1237*9c5db199SXin Li else: 1238*9c5db199SXin Li raise TypeError ('Argument must be one of StringTypes, EOF, TIMEOUT, SRE_Pattern, or a list of those type. %s' % str(type(p))) 1239*9c5db199SXin Li 1240*9c5db199SXin Li return compiled_pattern_list 1241*9c5db199SXin Li 1242*9c5db199SXin Li def expect(self, pattern, timeout = -1, searchwindowsize=None): 1243*9c5db199SXin Li 1244*9c5db199SXin Li """This seeks through the stream until a pattern is matched. The 1245*9c5db199SXin Li pattern is overloaded and may take several types. The pattern can be a 1246*9c5db199SXin Li StringType, EOF, a compiled re, or a list of any of those types. 1247*9c5db199SXin Li Strings will be compiled to re types. This returns the index into the 1248*9c5db199SXin Li pattern list. If the pattern was not a list this returns index 0 on a 1249*9c5db199SXin Li successful match. This may raise exceptions for EOF or TIMEOUT. To 1250*9c5db199SXin Li avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern 1251*9c5db199SXin Li list. That will cause expect to match an EOF or TIMEOUT condition 1252*9c5db199SXin Li instead of raising an exception. 1253*9c5db199SXin Li 1254*9c5db199SXin Li If you pass a list of patterns and more than one matches, the first match 1255*9c5db199SXin Li in the stream is chosen. If more than one pattern matches at that point, 1256*9c5db199SXin Li the leftmost in the pattern list is chosen. For example:: 1257*9c5db199SXin Li 1258*9c5db199SXin Li # the input is 'foobar' 1259*9c5db199SXin Li index = p.expect (['bar', 'foo', 'foobar']) 1260*9c5db199SXin Li # returns 1 ('foo') even though 'foobar' is a "better" match 1261*9c5db199SXin Li 1262*9c5db199SXin Li Please note, however, that buffering can affect this behavior, since 1263*9c5db199SXin Li input arrives in unpredictable chunks. For example:: 1264*9c5db199SXin Li 1265*9c5db199SXin Li # the input is 'foobar' 1266*9c5db199SXin Li index = p.expect (['foobar', 'foo']) 1267*9c5db199SXin Li # returns 0 ('foobar') if all input is available at once, 1268*9c5db199SXin Li # but returs 1 ('foo') if parts of the final 'bar' arrive late 1269*9c5db199SXin Li 1270*9c5db199SXin Li After a match is found the instance attributes 'before', 'after' and 1271*9c5db199SXin Li 'match' will be set. You can see all the data read before the match in 1272*9c5db199SXin Li 'before'. You can see the data that was matched in 'after'. The 1273*9c5db199SXin Li re.MatchObject used in the re match will be in 'match'. If an error 1274*9c5db199SXin Li occurred then 'before' will be set to all the data read so far and 1275*9c5db199SXin Li 'after' and 'match' will be None. 1276*9c5db199SXin Li 1277*9c5db199SXin Li If timeout is -1 then timeout will be set to the self.timeout value. 1278*9c5db199SXin Li 1279*9c5db199SXin Li A list entry may be EOF or TIMEOUT instead of a string. This will 1280*9c5db199SXin Li catch these exceptions and return the index of the list entry instead 1281*9c5db199SXin Li of raising the exception. The attribute 'after' will be set to the 1282*9c5db199SXin Li exception type. The attribute 'match' will be None. This allows you to 1283*9c5db199SXin Li write code like this:: 1284*9c5db199SXin Li 1285*9c5db199SXin Li index = p.expect (['good', 'bad', pexpect.EOF, pexpect.TIMEOUT]) 1286*9c5db199SXin Li if index == 0: 1287*9c5db199SXin Li do_something() 1288*9c5db199SXin Li elif index == 1: 1289*9c5db199SXin Li do_something_else() 1290*9c5db199SXin Li elif index == 2: 1291*9c5db199SXin Li do_some_other_thing() 1292*9c5db199SXin Li elif index == 3: 1293*9c5db199SXin Li do_something_completely_different() 1294*9c5db199SXin Li 1295*9c5db199SXin Li instead of code like this:: 1296*9c5db199SXin Li 1297*9c5db199SXin Li try: 1298*9c5db199SXin Li index = p.expect (['good', 'bad']) 1299*9c5db199SXin Li if index == 0: 1300*9c5db199SXin Li do_something() 1301*9c5db199SXin Li elif index == 1: 1302*9c5db199SXin Li do_something_else() 1303*9c5db199SXin Li except EOF: 1304*9c5db199SXin Li do_some_other_thing() 1305*9c5db199SXin Li except TIMEOUT: 1306*9c5db199SXin Li do_something_completely_different() 1307*9c5db199SXin Li 1308*9c5db199SXin Li These two forms are equivalent. It all depends on what you want. You 1309*9c5db199SXin Li can also just expect the EOF if you are waiting for all output of a 1310*9c5db199SXin Li child to finish. For example:: 1311*9c5db199SXin Li 1312*9c5db199SXin Li p = pexpect.spawn('/bin/ls') 1313*9c5db199SXin Li p.expect (pexpect.EOF) 1314*9c5db199SXin Li print p.before 1315*9c5db199SXin Li 1316*9c5db199SXin Li If you are trying to optimize for speed then see expect_list(). 1317*9c5db199SXin Li """ 1318*9c5db199SXin Li 1319*9c5db199SXin Li compiled_pattern_list = self.compile_pattern_list(pattern) 1320*9c5db199SXin Li return self.expect_list(compiled_pattern_list, timeout, searchwindowsize) 1321*9c5db199SXin Li 1322*9c5db199SXin Li def expect_list(self, pattern_list, timeout = -1, searchwindowsize = -1): 1323*9c5db199SXin Li 1324*9c5db199SXin Li """This takes a list of compiled regular expressions and returns the 1325*9c5db199SXin Li index into the pattern_list that matched the child output. The list may 1326*9c5db199SXin Li also contain EOF or TIMEOUT (which are not compiled regular 1327*9c5db199SXin Li expressions). This method is similar to the expect() method except that 1328*9c5db199SXin Li expect_list() does not recompile the pattern list on every call. This 1329*9c5db199SXin Li may help if you are trying to optimize for speed, otherwise just use 1330*9c5db199SXin Li the expect() method. This is called by expect(). If timeout==-1 then 1331*9c5db199SXin Li the self.timeout value is used. If searchwindowsize==-1 then the 1332*9c5db199SXin Li self.searchwindowsize value is used. """ 1333*9c5db199SXin Li 1334*9c5db199SXin Li return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize) 1335*9c5db199SXin Li 1336*9c5db199SXin Li def expect_exact(self, pattern_list, timeout = -1, searchwindowsize = -1): 1337*9c5db199SXin Li 1338*9c5db199SXin Li """This is similar to expect(), but uses plain string matching instead 1339*9c5db199SXin Li of compiled regular expressions in 'pattern_list'. The 'pattern_list' 1340*9c5db199SXin Li may be a string; a list or other sequence of strings; or TIMEOUT and 1341*9c5db199SXin Li EOF. 1342*9c5db199SXin Li 1343*9c5db199SXin Li This call might be faster than expect() for two reasons: string 1344*9c5db199SXin Li searching is faster than RE matching and it is possible to limit the 1345*9c5db199SXin Li search to just the end of the input buffer. 1346*9c5db199SXin Li 1347*9c5db199SXin Li This method is also useful when you don't want to have to worry about 1348*9c5db199SXin Li escaping regular expression characters that you want to match.""" 1349*9c5db199SXin Li 1350*9c5db199SXin Li if isinstance(pattern_list, six.string_types) or pattern_list in (TIMEOUT, EOF): 1351*9c5db199SXin Li pattern_list = [pattern_list] 1352*9c5db199SXin Li return self.expect_loop(searcher_string(pattern_list), timeout, searchwindowsize) 1353*9c5db199SXin Li 1354*9c5db199SXin Li def expect_loop(self, searcher, timeout = -1, searchwindowsize = -1): 1355*9c5db199SXin Li 1356*9c5db199SXin Li """This is the common loop used inside expect. The 'searcher' should be 1357*9c5db199SXin Li an instance of searcher_re or searcher_string, which describes how and what 1358*9c5db199SXin Li to search for in the input. 1359*9c5db199SXin Li 1360*9c5db199SXin Li See expect() for other arguments, return value and exceptions. """ 1361*9c5db199SXin Li 1362*9c5db199SXin Li self.searcher = searcher 1363*9c5db199SXin Li 1364*9c5db199SXin Li if timeout == -1: 1365*9c5db199SXin Li timeout = self.timeout 1366*9c5db199SXin Li if timeout is not None: 1367*9c5db199SXin Li end_time = time.time() + timeout 1368*9c5db199SXin Li if searchwindowsize == -1: 1369*9c5db199SXin Li searchwindowsize = self.searchwindowsize 1370*9c5db199SXin Li 1371*9c5db199SXin Li try: 1372*9c5db199SXin Li incoming = self.buffer 1373*9c5db199SXin Li freshlen = len(incoming) 1374*9c5db199SXin Li while True: # Keep reading until exception or return. 1375*9c5db199SXin Li index = searcher.search(incoming, freshlen, searchwindowsize) 1376*9c5db199SXin Li if index >= 0: 1377*9c5db199SXin Li self.buffer = incoming[searcher.end : ] 1378*9c5db199SXin Li self.before = incoming[ : searcher.start] 1379*9c5db199SXin Li self.after = incoming[searcher.start : searcher.end] 1380*9c5db199SXin Li self.match = searcher.match 1381*9c5db199SXin Li self.match_index = index 1382*9c5db199SXin Li return self.match_index 1383*9c5db199SXin Li # No match at this point 1384*9c5db199SXin Li if timeout < 0 and timeout is not None: 1385*9c5db199SXin Li raise TIMEOUT ('Timeout exceeded in expect_any().') 1386*9c5db199SXin Li # Still have time left, so read more data 1387*9c5db199SXin Li c = self.read_nonblocking (self.maxread, timeout) 1388*9c5db199SXin Li freshlen = len(c) 1389*9c5db199SXin Li time.sleep (0.0001) 1390*9c5db199SXin Li incoming = incoming + c 1391*9c5db199SXin Li if timeout is not None: 1392*9c5db199SXin Li timeout = end_time - time.time() 1393*9c5db199SXin Li except EOF as e: 1394*9c5db199SXin Li self.buffer = '' 1395*9c5db199SXin Li self.before = incoming 1396*9c5db199SXin Li self.after = EOF 1397*9c5db199SXin Li index = searcher.eof_index 1398*9c5db199SXin Li if index >= 0: 1399*9c5db199SXin Li self.match = EOF 1400*9c5db199SXin Li self.match_index = index 1401*9c5db199SXin Li return self.match_index 1402*9c5db199SXin Li else: 1403*9c5db199SXin Li self.match = None 1404*9c5db199SXin Li self.match_index = None 1405*9c5db199SXin Li raise EOF (str(e) + '\n' + str(self)) 1406*9c5db199SXin Li except TIMEOUT as e: 1407*9c5db199SXin Li self.buffer = incoming 1408*9c5db199SXin Li self.before = incoming 1409*9c5db199SXin Li self.after = TIMEOUT 1410*9c5db199SXin Li index = searcher.timeout_index 1411*9c5db199SXin Li if index >= 0: 1412*9c5db199SXin Li self.match = TIMEOUT 1413*9c5db199SXin Li self.match_index = index 1414*9c5db199SXin Li return self.match_index 1415*9c5db199SXin Li else: 1416*9c5db199SXin Li self.match = None 1417*9c5db199SXin Li self.match_index = None 1418*9c5db199SXin Li raise TIMEOUT (str(e) + '\n' + str(self)) 1419*9c5db199SXin Li except: 1420*9c5db199SXin Li self.before = incoming 1421*9c5db199SXin Li self.after = None 1422*9c5db199SXin Li self.match = None 1423*9c5db199SXin Li self.match_index = None 1424*9c5db199SXin Li raise 1425*9c5db199SXin Li 1426*9c5db199SXin Li def getwinsize(self): 1427*9c5db199SXin Li 1428*9c5db199SXin Li """This returns the terminal window size of the child tty. The return 1429*9c5db199SXin Li value is a tuple of (rows, cols). """ 1430*9c5db199SXin Li 1431*9c5db199SXin Li TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912) 1432*9c5db199SXin Li s = struct.pack('HHHH', 0, 0, 0, 0) 1433*9c5db199SXin Li x = fcntl.ioctl(self.fileno(), TIOCGWINSZ, s) 1434*9c5db199SXin Li return struct.unpack('HHHH', x)[0:2] 1435*9c5db199SXin Li 1436*9c5db199SXin Li def setwinsize(self, r, c): 1437*9c5db199SXin Li 1438*9c5db199SXin Li """This sets the terminal window size of the child tty. This will cause 1439*9c5db199SXin Li a SIGWINCH signal to be sent to the child. This does not change the 1440*9c5db199SXin Li physical window size. It changes the size reported to TTY-aware 1441*9c5db199SXin Li applications like vi or curses -- applications that respond to the 1442*9c5db199SXin Li SIGWINCH signal. """ 1443*9c5db199SXin Li 1444*9c5db199SXin Li # Check for buggy platforms. Some Python versions on some platforms 1445*9c5db199SXin Li # (notably OSF1 Alpha and RedHat 7.1) truncate the value for 1446*9c5db199SXin Li # termios.TIOCSWINSZ. It is not clear why this happens. 1447*9c5db199SXin Li # These platforms don't seem to handle the signed int very well; 1448*9c5db199SXin Li # yet other platforms like OpenBSD have a large negative value for 1449*9c5db199SXin Li # TIOCSWINSZ and they don't have a truncate problem. 1450*9c5db199SXin Li # Newer versions of Linux have totally different values for TIOCSWINSZ. 1451*9c5db199SXin Li # Note that this fix is a hack. 1452*9c5db199SXin Li TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) 1453*9c5db199SXin Li if TIOCSWINSZ == 2148037735: 1454*9c5db199SXin Li TIOCSWINSZ = -2146929561 # Same bits, but with sign. 1455*9c5db199SXin Li # Note, assume ws_xpixel and ws_ypixel are zero. 1456*9c5db199SXin Li s = struct.pack('HHHH', r, c, 0, 0) 1457*9c5db199SXin Li fcntl.ioctl(self.fileno(), TIOCSWINSZ, s) 1458*9c5db199SXin Li 1459*9c5db199SXin Li def interact(self, escape_character = chr(29), input_filter = None, output_filter = None): 1460*9c5db199SXin Li 1461*9c5db199SXin Li """This gives control of the child process to the interactive user (the 1462*9c5db199SXin Li human at the keyboard). Keystrokes are sent to the child process, and 1463*9c5db199SXin Li the stdout and stderr output of the child process is printed. This 1464*9c5db199SXin Li simply echos the child stdout and child stderr to the real stdout and 1465*9c5db199SXin Li it echos the real stdin to the child stdin. When the user types the 1466*9c5db199SXin Li escape_character this method will stop. The default for 1467*9c5db199SXin Li escape_character is ^]. This should not be confused with ASCII 27 -- 1468*9c5db199SXin Li the ESC character. ASCII 29 was chosen for historical merit because 1469*9c5db199SXin Li this is the character used by 'telnet' as the escape character. The 1470*9c5db199SXin Li escape_character will not be sent to the child process. 1471*9c5db199SXin Li 1472*9c5db199SXin Li You may pass in optional input and output filter functions. These 1473*9c5db199SXin Li functions should take a string and return a string. The output_filter 1474*9c5db199SXin Li will be passed all the output from the child process. The input_filter 1475*9c5db199SXin Li will be passed all the keyboard input from the user. The input_filter 1476*9c5db199SXin Li is run BEFORE the check for the escape_character. 1477*9c5db199SXin Li 1478*9c5db199SXin Li Note that if you change the window size of the parent the SIGWINCH 1479*9c5db199SXin Li signal will not be passed through to the child. If you want the child 1480*9c5db199SXin Li window size to change when the parent's window size changes then do 1481*9c5db199SXin Li something like the following example:: 1482*9c5db199SXin Li 1483*9c5db199SXin Li import pexpect, struct, fcntl, termios, signal, sys 1484*9c5db199SXin Li def sigwinch_passthrough (sig, data): 1485*9c5db199SXin Li s = struct.pack("HHHH", 0, 0, 0, 0) 1486*9c5db199SXin Li a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ , s)) 1487*9c5db199SXin Li global p 1488*9c5db199SXin Li p.setwinsize(a[0],a[1]) 1489*9c5db199SXin Li p = pexpect.spawn('/bin/bash') # Note this is global and used in sigwinch_passthrough. 1490*9c5db199SXin Li signal.signal(signal.SIGWINCH, sigwinch_passthrough) 1491*9c5db199SXin Li p.interact() 1492*9c5db199SXin Li """ 1493*9c5db199SXin Li 1494*9c5db199SXin Li # Flush the buffer. 1495*9c5db199SXin Li self.stdout.write (self.buffer) 1496*9c5db199SXin Li self.stdout.flush() 1497*9c5db199SXin Li self.buffer = '' 1498*9c5db199SXin Li mode = tty.tcgetattr(self.STDIN_FILENO) 1499*9c5db199SXin Li tty.setraw(self.STDIN_FILENO) 1500*9c5db199SXin Li try: 1501*9c5db199SXin Li self.__interact_copy(escape_character, input_filter, output_filter) 1502*9c5db199SXin Li finally: 1503*9c5db199SXin Li tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) 1504*9c5db199SXin Li 1505*9c5db199SXin Li def __interact_writen(self, fd, data): 1506*9c5db199SXin Li 1507*9c5db199SXin Li """This is used by the interact() method. 1508*9c5db199SXin Li """ 1509*9c5db199SXin Li 1510*9c5db199SXin Li while data != '' and self.isalive(): 1511*9c5db199SXin Li n = os.write(fd, data) 1512*9c5db199SXin Li data = data[n:] 1513*9c5db199SXin Li 1514*9c5db199SXin Li def __interact_read(self, fd): 1515*9c5db199SXin Li 1516*9c5db199SXin Li """This is used by the interact() method. 1517*9c5db199SXin Li """ 1518*9c5db199SXin Li 1519*9c5db199SXin Li return os.read(fd, 1000) 1520*9c5db199SXin Li 1521*9c5db199SXin Li def __interact_copy(self, escape_character = None, input_filter = None, output_filter = None): 1522*9c5db199SXin Li 1523*9c5db199SXin Li """This is used by the interact() method. 1524*9c5db199SXin Li """ 1525*9c5db199SXin Li 1526*9c5db199SXin Li while self.isalive(): 1527*9c5db199SXin Li r,w,e = self.__select([self.child_fd, self.STDIN_FILENO], [], []) 1528*9c5db199SXin Li if self.child_fd in r: 1529*9c5db199SXin Li data = self.__interact_read(self.child_fd) 1530*9c5db199SXin Li if output_filter: data = output_filter(data) 1531*9c5db199SXin Li if self.logfile is not None: 1532*9c5db199SXin Li self.logfile.write (data) 1533*9c5db199SXin Li self.logfile.flush() 1534*9c5db199SXin Li os.write(self.STDOUT_FILENO, data) 1535*9c5db199SXin Li if self.STDIN_FILENO in r: 1536*9c5db199SXin Li data = self.__interact_read(self.STDIN_FILENO) 1537*9c5db199SXin Li if input_filter: data = input_filter(data) 1538*9c5db199SXin Li i = data.rfind(escape_character) 1539*9c5db199SXin Li if i != -1: 1540*9c5db199SXin Li data = data[:i] 1541*9c5db199SXin Li self.__interact_writen(self.child_fd, data) 1542*9c5db199SXin Li break 1543*9c5db199SXin Li self.__interact_writen(self.child_fd, data) 1544*9c5db199SXin Li 1545*9c5db199SXin Li def __select (self, iwtd, owtd, ewtd, timeout=None): 1546*9c5db199SXin Li 1547*9c5db199SXin Li """This is a wrapper around select.select() that ignores signals. If 1548*9c5db199SXin Li select.select raises a select.error exception and errno is an EINTR 1549*9c5db199SXin Li error then it is ignored. Mainly this is used to ignore sigwinch 1550*9c5db199SXin Li (terminal resize). """ 1551*9c5db199SXin Li 1552*9c5db199SXin Li # if select() is interrupted by a signal (errno==EINTR) then 1553*9c5db199SXin Li # we loop back and enter the select() again. 1554*9c5db199SXin Li if timeout is not None: 1555*9c5db199SXin Li end_time = time.time() + timeout 1556*9c5db199SXin Li while True: 1557*9c5db199SXin Li try: 1558*9c5db199SXin Li return select.select (iwtd, owtd, ewtd, timeout) 1559*9c5db199SXin Li except select.error as e: 1560*9c5db199SXin Li if e[0] == errno.EINTR: 1561*9c5db199SXin Li # if we loop back we have to subtract the amount of time we already waited. 1562*9c5db199SXin Li if timeout is not None: 1563*9c5db199SXin Li timeout = end_time - time.time() 1564*9c5db199SXin Li if timeout < 0: 1565*9c5db199SXin Li return ([],[],[]) 1566*9c5db199SXin Li else: # something else caused the select.error, so this really is an exception 1567*9c5db199SXin Li raise 1568*9c5db199SXin Li 1569*9c5db199SXin Li############################################################################## 1570*9c5db199SXin Li# The following methods are no longer supported or allowed. 1571*9c5db199SXin Li 1572*9c5db199SXin Li def setmaxread (self, maxread): 1573*9c5db199SXin Li 1574*9c5db199SXin Li """This method is no longer supported or allowed. I don't like getters 1575*9c5db199SXin Li and setters without a good reason. """ 1576*9c5db199SXin Li 1577*9c5db199SXin Li raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the maxread member variable.') 1578*9c5db199SXin Li 1579*9c5db199SXin Li def setlog (self, fileobject): 1580*9c5db199SXin Li 1581*9c5db199SXin Li """This method is no longer supported or allowed. 1582*9c5db199SXin Li """ 1583*9c5db199SXin Li 1584*9c5db199SXin Li raise ExceptionPexpect ('This method is no longer supported or allowed. Just assign a value to the logfile member variable.') 1585*9c5db199SXin Li 1586*9c5db199SXin Li############################################################################## 1587*9c5db199SXin Li# End of spawn class 1588*9c5db199SXin Li############################################################################## 1589*9c5db199SXin Li 1590*9c5db199SXin Liclass searcher_string (object): 1591*9c5db199SXin Li 1592*9c5db199SXin Li """This is a plain string search helper for the spawn.expect_any() method. 1593*9c5db199SXin Li 1594*9c5db199SXin Li Attributes: 1595*9c5db199SXin Li 1596*9c5db199SXin Li eof_index - index of EOF, or -1 1597*9c5db199SXin Li timeout_index - index of TIMEOUT, or -1 1598*9c5db199SXin Li 1599*9c5db199SXin Li After a successful match by the search() method the following attributes 1600*9c5db199SXin Li are available: 1601*9c5db199SXin Li 1602*9c5db199SXin Li start - index into the buffer, first byte of match 1603*9c5db199SXin Li end - index into the buffer, first byte after match 1604*9c5db199SXin Li match - the matching string itself 1605*9c5db199SXin Li """ 1606*9c5db199SXin Li 1607*9c5db199SXin Li def __init__(self, strings): 1608*9c5db199SXin Li 1609*9c5db199SXin Li """This creates an instance of searcher_string. This argument 'strings' 1610*9c5db199SXin Li may be a list; a sequence of strings; or the EOF or TIMEOUT types. """ 1611*9c5db199SXin Li 1612*9c5db199SXin Li self.eof_index = -1 1613*9c5db199SXin Li self.timeout_index = -1 1614*9c5db199SXin Li self._strings = [] 1615*9c5db199SXin Li for n, s in zip(range(len(strings)), strings): 1616*9c5db199SXin Li if s is EOF: 1617*9c5db199SXin Li self.eof_index = n 1618*9c5db199SXin Li continue 1619*9c5db199SXin Li if s is TIMEOUT: 1620*9c5db199SXin Li self.timeout_index = n 1621*9c5db199SXin Li continue 1622*9c5db199SXin Li self._strings.append((n, s)) 1623*9c5db199SXin Li 1624*9c5db199SXin Li def __str__(self): 1625*9c5db199SXin Li 1626*9c5db199SXin Li """This returns a human-readable string that represents the state of 1627*9c5db199SXin Li the object.""" 1628*9c5db199SXin Li 1629*9c5db199SXin Li ss = [ (ns[0],' %d: "%s"' % ns) for ns in self._strings ] 1630*9c5db199SXin Li ss.append((-1,'searcher_string:')) 1631*9c5db199SXin Li if self.eof_index >= 0: 1632*9c5db199SXin Li ss.append ((self.eof_index,' %d: EOF' % self.eof_index)) 1633*9c5db199SXin Li if self.timeout_index >= 0: 1634*9c5db199SXin Li ss.append ((self.timeout_index,' %d: TIMEOUT' % self.timeout_index)) 1635*9c5db199SXin Li ss.sort() 1636*9c5db199SXin Li ss = list(zip(*ss))[1] 1637*9c5db199SXin Li return '\n'.join(ss) 1638*9c5db199SXin Li 1639*9c5db199SXin Li def search(self, buffer, freshlen, searchwindowsize=None): 1640*9c5db199SXin Li 1641*9c5db199SXin Li """This searches 'buffer' for the first occurence of one of the search 1642*9c5db199SXin Li strings. 'freshlen' must indicate the number of bytes at the end of 1643*9c5db199SXin Li 'buffer' which have not been searched before. It helps to avoid 1644*9c5db199SXin Li searching the same, possibly big, buffer over and over again. 1645*9c5db199SXin Li 1646*9c5db199SXin Li See class spawn for the 'searchwindowsize' argument. 1647*9c5db199SXin Li 1648*9c5db199SXin Li If there is a match this returns the index of that string, and sets 1649*9c5db199SXin Li 'start', 'end' and 'match'. Otherwise, this returns -1. """ 1650*9c5db199SXin Li 1651*9c5db199SXin Li absurd_match = len(buffer) 1652*9c5db199SXin Li first_match = absurd_match 1653*9c5db199SXin Li 1654*9c5db199SXin Li # 'freshlen' helps a lot here. Further optimizations could 1655*9c5db199SXin Li # possibly include: 1656*9c5db199SXin Li # 1657*9c5db199SXin Li # using something like the Boyer-Moore Fast String Searching 1658*9c5db199SXin Li # Algorithm; pre-compiling the search through a list of 1659*9c5db199SXin Li # strings into something that can scan the input once to 1660*9c5db199SXin Li # search for all N strings; realize that if we search for 1661*9c5db199SXin Li # ['bar', 'baz'] and the input is '...foo' we need not bother 1662*9c5db199SXin Li # rescanning until we've read three more bytes. 1663*9c5db199SXin Li # 1664*9c5db199SXin Li # Sadly, I don't know enough about this interesting topic. /grahn 1665*9c5db199SXin Li 1666*9c5db199SXin Li for index, s in self._strings: 1667*9c5db199SXin Li if searchwindowsize is None: 1668*9c5db199SXin Li # the match, if any, can only be in the fresh data, 1669*9c5db199SXin Li # or at the very end of the old data 1670*9c5db199SXin Li offset = -(freshlen+len(s)) 1671*9c5db199SXin Li else: 1672*9c5db199SXin Li # better obey searchwindowsize 1673*9c5db199SXin Li offset = -searchwindowsize 1674*9c5db199SXin Li n = buffer.find(s, offset) 1675*9c5db199SXin Li if n >= 0 and n < first_match: 1676*9c5db199SXin Li first_match = n 1677*9c5db199SXin Li best_index, best_match = index, s 1678*9c5db199SXin Li if first_match == absurd_match: 1679*9c5db199SXin Li return -1 1680*9c5db199SXin Li self.match = best_match 1681*9c5db199SXin Li self.start = first_match 1682*9c5db199SXin Li self.end = self.start + len(self.match) 1683*9c5db199SXin Li return best_index 1684*9c5db199SXin Li 1685*9c5db199SXin Liclass searcher_re (object): 1686*9c5db199SXin Li 1687*9c5db199SXin Li """This is regular expression string search helper for the 1688*9c5db199SXin Li spawn.expect_any() method. 1689*9c5db199SXin Li 1690*9c5db199SXin Li Attributes: 1691*9c5db199SXin Li 1692*9c5db199SXin Li eof_index - index of EOF, or -1 1693*9c5db199SXin Li timeout_index - index of TIMEOUT, or -1 1694*9c5db199SXin Li 1695*9c5db199SXin Li After a successful match by the search() method the following attributes 1696*9c5db199SXin Li are available: 1697*9c5db199SXin Li 1698*9c5db199SXin Li start - index into the buffer, first byte of match 1699*9c5db199SXin Li end - index into the buffer, first byte after match 1700*9c5db199SXin Li match - the re.match object returned by a succesful re.search 1701*9c5db199SXin Li 1702*9c5db199SXin Li """ 1703*9c5db199SXin Li 1704*9c5db199SXin Li def __init__(self, patterns): 1705*9c5db199SXin Li 1706*9c5db199SXin Li """This creates an instance that searches for 'patterns' Where 1707*9c5db199SXin Li 'patterns' may be a list or other sequence of compiled regular 1708*9c5db199SXin Li expressions, or the EOF or TIMEOUT types.""" 1709*9c5db199SXin Li 1710*9c5db199SXin Li self.eof_index = -1 1711*9c5db199SXin Li self.timeout_index = -1 1712*9c5db199SXin Li self._searches = [] 1713*9c5db199SXin Li for n, s in zip(range(len(patterns)), patterns): 1714*9c5db199SXin Li if s is EOF: 1715*9c5db199SXin Li self.eof_index = n 1716*9c5db199SXin Li continue 1717*9c5db199SXin Li if s is TIMEOUT: 1718*9c5db199SXin Li self.timeout_index = n 1719*9c5db199SXin Li continue 1720*9c5db199SXin Li self._searches.append((n, s)) 1721*9c5db199SXin Li 1722*9c5db199SXin Li def __str__(self): 1723*9c5db199SXin Li 1724*9c5db199SXin Li """This returns a human-readable string that represents the state of 1725*9c5db199SXin Li the object.""" 1726*9c5db199SXin Li 1727*9c5db199SXin Li ss = [ (n,' %d: re.compile("%s")' % (n,str(s.pattern))) for n,s in self._searches] 1728*9c5db199SXin Li ss.append((-1,'searcher_re:')) 1729*9c5db199SXin Li if self.eof_index >= 0: 1730*9c5db199SXin Li ss.append ((self.eof_index,' %d: EOF' % self.eof_index)) 1731*9c5db199SXin Li if self.timeout_index >= 0: 1732*9c5db199SXin Li ss.append ((self.timeout_index,' %d: TIMEOUT' % self.timeout_index)) 1733*9c5db199SXin Li ss.sort() 1734*9c5db199SXin Li ss = list(zip(*ss))[1] 1735*9c5db199SXin Li return '\n'.join(ss) 1736*9c5db199SXin Li 1737*9c5db199SXin Li def search(self, buffer, freshlen, searchwindowsize=None): 1738*9c5db199SXin Li 1739*9c5db199SXin Li """This searches 'buffer' for the first occurence of one of the regular 1740*9c5db199SXin Li expressions. 'freshlen' must indicate the number of bytes at the end of 1741*9c5db199SXin Li 'buffer' which have not been searched before. 1742*9c5db199SXin Li 1743*9c5db199SXin Li See class spawn for the 'searchwindowsize' argument. 1744*9c5db199SXin Li 1745*9c5db199SXin Li If there is a match this returns the index of that string, and sets 1746*9c5db199SXin Li 'start', 'end' and 'match'. Otherwise, returns -1.""" 1747*9c5db199SXin Li 1748*9c5db199SXin Li absurd_match = len(buffer) 1749*9c5db199SXin Li first_match = absurd_match 1750*9c5db199SXin Li # 'freshlen' doesn't help here -- we cannot predict the 1751*9c5db199SXin Li # length of a match, and the re module provides no help. 1752*9c5db199SXin Li if searchwindowsize is None: 1753*9c5db199SXin Li searchstart = 0 1754*9c5db199SXin Li else: 1755*9c5db199SXin Li searchstart = max(0, len(buffer)-searchwindowsize) 1756*9c5db199SXin Li for index, s in self._searches: 1757*9c5db199SXin Li match = s.search(buffer, searchstart) 1758*9c5db199SXin Li if match is None: 1759*9c5db199SXin Li continue 1760*9c5db199SXin Li n = match.start() 1761*9c5db199SXin Li if n < first_match: 1762*9c5db199SXin Li first_match = n 1763*9c5db199SXin Li the_match = match 1764*9c5db199SXin Li best_index = index 1765*9c5db199SXin Li if first_match == absurd_match: 1766*9c5db199SXin Li return -1 1767*9c5db199SXin Li self.start = first_match 1768*9c5db199SXin Li self.match = the_match 1769*9c5db199SXin Li self.end = self.match.end() 1770*9c5db199SXin Li return best_index 1771*9c5db199SXin Li 1772*9c5db199SXin Lidef which (filename): 1773*9c5db199SXin Li 1774*9c5db199SXin Li """This takes a given filename; tries to find it in the environment path; 1775*9c5db199SXin Li then checks if it is executable. This returns the full path to the filename 1776*9c5db199SXin Li if found and executable. Otherwise this returns None.""" 1777*9c5db199SXin Li 1778*9c5db199SXin Li # Special case where filename already contains a path. 1779*9c5db199SXin Li if os.path.dirname(filename) != '': 1780*9c5db199SXin Li if os.access (filename, os.X_OK): 1781*9c5db199SXin Li return filename 1782*9c5db199SXin Li 1783*9c5db199SXin Li p = os.getenv('PATH') or os.defpath 1784*9c5db199SXin Li 1785*9c5db199SXin Li # Oddly enough this was the one line that made Pexpect 1786*9c5db199SXin Li # incompatible with Python 1.5.2. 1787*9c5db199SXin Li #pathlist = p.split (os.pathsep) 1788*9c5db199SXin Li pathlist = string.split (p, os.pathsep) 1789*9c5db199SXin Li 1790*9c5db199SXin Li for path in pathlist: 1791*9c5db199SXin Li f = os.path.join(path, filename) 1792*9c5db199SXin Li if os.access(f, os.X_OK): 1793*9c5db199SXin Li return f 1794*9c5db199SXin Li return None 1795*9c5db199SXin Li 1796*9c5db199SXin Lidef split_command_line(command_line): 1797*9c5db199SXin Li 1798*9c5db199SXin Li """This splits a command line into a list of arguments. It splits arguments 1799*9c5db199SXin Li on spaces, but handles embedded quotes, doublequotes, and escaped 1800*9c5db199SXin Li characters. It's impossible to do this with a regular expression, so I 1801*9c5db199SXin Li wrote a little state machine to parse the command line. """ 1802*9c5db199SXin Li 1803*9c5db199SXin Li arg_list = [] 1804*9c5db199SXin Li arg = '' 1805*9c5db199SXin Li 1806*9c5db199SXin Li # Constants to name the states we can be in. 1807*9c5db199SXin Li state_basic = 0 1808*9c5db199SXin Li state_esc = 1 1809*9c5db199SXin Li state_singlequote = 2 1810*9c5db199SXin Li state_doublequote = 3 1811*9c5db199SXin Li state_whitespace = 4 # The state of consuming whitespace between commands. 1812*9c5db199SXin Li state = state_basic 1813*9c5db199SXin Li 1814*9c5db199SXin Li for c in command_line: 1815*9c5db199SXin Li if state == state_basic or state == state_whitespace: 1816*9c5db199SXin Li if c == '\\': # Escape the next character 1817*9c5db199SXin Li state = state_esc 1818*9c5db199SXin Li elif c == r"'": # Handle single quote 1819*9c5db199SXin Li state = state_singlequote 1820*9c5db199SXin Li elif c == r'"': # Handle double quote 1821*9c5db199SXin Li state = state_doublequote 1822*9c5db199SXin Li elif c.isspace(): 1823*9c5db199SXin Li # Add arg to arg_list if we aren't in the middle of whitespace. 1824*9c5db199SXin Li if state == state_whitespace: 1825*9c5db199SXin Li None # Do nothing. 1826*9c5db199SXin Li else: 1827*9c5db199SXin Li arg_list.append(arg) 1828*9c5db199SXin Li arg = '' 1829*9c5db199SXin Li state = state_whitespace 1830*9c5db199SXin Li else: 1831*9c5db199SXin Li arg = arg + c 1832*9c5db199SXin Li state = state_basic 1833*9c5db199SXin Li elif state == state_esc: 1834*9c5db199SXin Li arg = arg + c 1835*9c5db199SXin Li state = state_basic 1836*9c5db199SXin Li elif state == state_singlequote: 1837*9c5db199SXin Li if c == r"'": 1838*9c5db199SXin Li state = state_basic 1839*9c5db199SXin Li else: 1840*9c5db199SXin Li arg = arg + c 1841*9c5db199SXin Li elif state == state_doublequote: 1842*9c5db199SXin Li if c == r'"': 1843*9c5db199SXin Li state = state_basic 1844*9c5db199SXin Li else: 1845*9c5db199SXin Li arg = arg + c 1846*9c5db199SXin Li 1847*9c5db199SXin Li if arg != '': 1848*9c5db199SXin Li arg_list.append(arg) 1849*9c5db199SXin Li return arg_list 1850*9c5db199SXin Li 1851*9c5db199SXin Li# vi:ts=4:sw=4:expandtab:ft=python: 1852