From 03e20dc08c0a4ab5f1d26666745acdec1441017c Mon Sep 17 00:00:00 2001 From: Benedek Racz Date: Tue, 4 Feb 2020 10:45:11 +0100 Subject: [PATCH] minimal 19 --- wexpect/host.py | 244 ------------------------------------------------ 1 file changed, 244 deletions(-) diff --git a/wexpect/host.py b/wexpect/host.py index 124eba4..adfbe8b 100644 --- a/wexpect/host.py +++ b/wexpect/host.py @@ -96,114 +96,6 @@ logger = logging.getLogger('wexpect') init_logger(logger) -def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, - cwd=None, env=None, **kwargs): - """ - This function runs the given command; waits for it to finish; then - returns all output as a string. STDERR is included in output. If the full - path to the command is not given then the path is searched. - - Note that lines are terminated by CR/LF (\\r\\n) combination even on - UNIX-like systems because this is the standard for pseudo ttys. If you set - 'withexitstatus' to true, then run will return a tuple of (command_output, - exitstatus). If 'withexitstatus' is false then this returns just - command_output. - - The run() function can often be used instead of creating a spawn instance. - For example, the following code uses spawn:: - - child = spawn('scp foo myname@host.example.com:.') - child.expect ('(?i)password') - child.sendline (mypassword) - - The previous code can be replace with the following:: - - Examples - ======== - - Start the apache daemon on the local machine:: - - run ("/usr/local/apache/bin/apachectl start") - - Check in a file using SVN:: - - run ("svn ci -m 'automatic commit' my_file.py") - - Run a command and capture exit status:: - - (command_output, exitstatus) = run ('ls -l /bin', withexitstatus=1) - - Tricky Examples - =============== - - The following will run SSH and execute 'ls -l' on the remote machine. The - password 'secret' will be sent if the '(?i)password' pattern is ever seen:: - - run ("ssh username@machine.example.com 'ls -l'", events={'(?i)password':'secret\\n'}) - - This will start mencoder to rip a video from DVD. This will also display - progress ticks every 5 seconds as it runs. For example:: - - The 'events' argument should be a dictionary of patterns and responses. - Whenever one of the patterns is seen in the command out run() will send the - associated response string. Note that you should put newlines in your - string if Enter is necessary. The responses may also contain callback - functions. Any callback is function that takes a dictionary as an argument. - The dictionary contains all the locals from the run() function, so you can - access the child spawn object or any other variable defined in run() - (event_count, child, and extra_args are the most useful). A callback may - return True to stop the current run process otherwise run() continues until - the next event. A callback may also return a string which will be sent to - the child. 'extra_args' is not used by directly run(). It provides a way to - pass data to a callback function through run() through the locals - dictionary passed to a callback. """ - - from .__init__ import spawn - if timeout == -1: - child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env, **kwargs) - else: - child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile, cwd=cwd, env=env, **kwargs) - if events is not None: - patterns = list(events.keys()) - responses = list(events.values()) - else: - patterns=None # We assume that EOF or TIMEOUT will save us. - responses=None - child_result_list = [] - event_count = 0 - while 1: - try: - index = child.expect (patterns) - if type(child.after) in (str,): - child_result_list.append(child.before + child.after) - else: # child.after may have been a TIMEOUT or EOF, so don't cat those. - child_result_list.append(child.before) - if type(responses[index]) in (str,): - child.send(responses[index]) - elif type(responses[index]) is types.FunctionType: - callback_result = responses[index](locals()) - sys.stdout.flush() - if type(callback_result) in (str,): - child.send(callback_result) - elif callback_result: - break - else: - logger.warning("TypeError ('The callback must be a string or function type.')") - raise TypeError ('The callback must be a string or function type.') - event_count = event_count + 1 - except TIMEOUT: - child_result_list.append(child.before) - break - except EOF: - child_result_list.append(child.before) - break - child_result = ''.join(child_result_list) - if withexitstatus: - child.wait() - return (child_result, child.exitstatus) - else: - return child_result - class SpawnBase: def __init__(self, command, args=[], timeout=30, maxread=60000, searchwindowsize=None, @@ -303,34 +195,6 @@ class SpawnBase: traceback.print_exc() logger.warning(traceback.format_exc()) - def __str__(self): - """This returns a human-readable string that represents the state of - the object. """ - - s = [] - s.append(repr(self)) - s.append('command: ' + str(self.command)) - s.append('args: ' + str(self.args)) - s.append('searcher: ' + str(self.searcher)) - s.append('buffer (last 100 chars): ' + str(self.buffer)[-100:]) - s.append('before (last 100 chars): ' + str(self.before)[-100:]) - s.append('after: ' + str(self.after)) - s.append('match: ' + str(self.match)) - s.append('match_index: ' + str(self.match_index)) - s.append('exitstatus: ' + str(self.exitstatus)) - s.append('flag_eof: ' + str(self.flag_eof)) - s.append('host_pid: ' + str(self.host_pid)) - s.append('child_fd: ' + str(self.child_fd)) - s.append('closed: ' + str(self.closed)) - s.append('timeout: ' + str(self.timeout)) - s.append('delimiter: ' + str(self.delimiter)) - s.append('maxread: ' + str(self.maxread)) - s.append('ignorecase: ' + str(self.ignorecase)) - s.append('searchwindowsize: ' + str(self.searchwindowsize)) - s.append('delaybeforesend: ' + str(self.delaybeforesend)) - s.append('delayafterterminate: ' + str(self.delayafterterminate)) - return '\n'.join(s) - def startChild(self, args, env): si = win32process.GetStartupInfo() si.dwFlags = win32process.STARTF_USESHOWWINDOW @@ -411,114 +275,6 @@ class SpawnPipe(SpawnBase): self.delayafterterminate = 1 # Sets delay in terminate() method to allow kernel time to update process status. Time in seconds. - def connect_to_child(self): - pipe_name = 'wexpect_{}'.format(self.console_pid) - pipe_full_path = r'\\.\pipe\{}'.format(pipe_name) - logger.debug(f'Trying to connect to pipe: {pipe_full_path}') - while True: - try: - self.pipe = win32file.CreateFile( - pipe_full_path, - win32file.GENERIC_READ | win32file.GENERIC_WRITE, - 0, - None, - win32file.OPEN_EXISTING, - 0, - None - ) - logger.debug('Pipe found') - res = win32pipe.SetNamedPipeHandleState(self.pipe, win32pipe.PIPE_READMODE_MESSAGE, None, None) - if res == 0: - logger.debug(f"SetNamedPipeHandleState return code: {res}") - return - except pywintypes.error as e: - if e.args[0] == winerror.ERROR_FILE_NOT_FOUND: #2 - logger.debug("no pipe, trying again in a bit later") - time.sleep(0.2) - else: - raise - - def disconnect_from_child(self): - if self.pipe: - win32file.CloseHandle(self.pipe) - - def read_nonblocking (self, size = 1): - """This reads at most size characters from the child application. If - the end of file is read then an EOF exception will be raised. - - This is not effected by the 'size' parameter, so if you call - read_nonblocking(size=100, timeout=30) and only one character is - available right away then one character will be returned immediately. - It will not wait for 30 seconds for another 99 characters to come in. - - This is a wrapper around Wtty.read(). """ - - if self.closed: - logger.warning('I/O operation on closed file in read_nonblocking().') - raise ValueError ('I/O operation on closed file in read_nonblocking().') - - try: - s = win32file.ReadFile(self.pipe, size)[1] - - if s: - logger.debug(f'Readed: {s}') - else: - logger.spam(f'Readed: {s}') - - if b'\x04' in s: - self.flag_eof = True - logger.info("EOF: EOF character has been arrived") - raise EOF('EOF character has been arrived') - - return s.decode() - except pywintypes.error as e: - if e.args[0] == winerror.ERROR_BROKEN_PIPE: #109 - self.flag_eof = True - logger.info("EOF('broken pipe, bye bye')") - raise EOF('broken pipe, bye bye') - elif e.args[0] == winerror.ERROR_NO_DATA: - '''232 (0xE8): The pipe is being closed. - ''' - self.flag_eof = True - logger.info("EOF('The pipe is being closed.')") - raise EOF('The pipe is being closed.') - else: - raise - - def _send_impl(self, s): - """This sends a string to the child process. This returns the number of - bytes written. If a log file was set then the data is also written to - the log. """ - if isinstance(s, str): - s = str.encode(s) - try: - if s: - logger.debug(f"Writing: {s}") - win32file.WriteFile(self.pipe, s) - logger.spam(f"WriteFile finished.") - except pywintypes.error as e: - if e.args[0] == winerror.ERROR_BROKEN_PIPE: #109 - logger.info("EOF: broken pipe, bye bye") - raise EOF("broken pipe, bye bye") - elif e.args[0] == winerror.ERROR_NO_DATA: - '''232 (0xE8) - The pipe is being closed. - ''' - logger.info("The pipe is being closed.") - raise EOF("The pipe is being closed.") - else: - raise - return len(s) - - def kill(self, sig=signal.SIGTERM): - """Sig == sigint for ctrl-c otherwise the child is terminated.""" - try: - logger.info(f'Sending kill signal: {sig}') - self.send(SIGNAL_CHARS[sig]) - self.terminated = True - except EOF as e: - logger.info(e) - class SpawnSocket(SpawnBase): pass