You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			158 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Python
		
	
			
		
		
	
	
			158 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Python
		
	
import sys
 | 
						|
import types
 | 
						|
 | 
						|
from .exceptions import EOF, TIMEOUT
 | 
						|
from .pty_spawn import spawn
 | 
						|
 | 
						|
def run(command, timeout=30, 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 pseudottys. 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::
 | 
						|
 | 
						|
        from pexpect import *
 | 
						|
        child = spawn('scp foo user@example.com:.')
 | 
						|
        child.expect('(?i)password')
 | 
						|
        child.sendline(mypassword)
 | 
						|
 | 
						|
    The previous code can be replace with the following::
 | 
						|
 | 
						|
        from pexpect import *
 | 
						|
        run('scp foo user@example.com:.', events={'(?i)password': mypassword})
 | 
						|
 | 
						|
    **Examples**
 | 
						|
 | 
						|
    Start the apache daemon on the local machine::
 | 
						|
 | 
						|
        from pexpect import *
 | 
						|
        run("/usr/local/apache/bin/apachectl start")
 | 
						|
 | 
						|
    Check in a file using SVN::
 | 
						|
 | 
						|
        from pexpect import *
 | 
						|
        run("svn ci -m 'automatic commit' my_file.py")
 | 
						|
 | 
						|
    Run a command and capture exit status::
 | 
						|
 | 
						|
        from pexpect import *
 | 
						|
        (command_output, exitstatus) = run('ls -l /bin', withexitstatus=1)
 | 
						|
 | 
						|
    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::
 | 
						|
 | 
						|
        from pexpect import *
 | 
						|
        def print_ticks(d):
 | 
						|
            print d['event_count'],
 | 
						|
        run("mencoder dvd://1 -o video.avi -oac copy -ovc copy",
 | 
						|
            events={TIMEOUT:print_ticks}, timeout=5)
 | 
						|
 | 
						|
    The 'events' argument should be either a dictionary or a tuple list that
 | 
						|
    contains patterns and responses. Whenever one of the patterns is seen
 | 
						|
    in the command output, run() will send the associated response string.
 | 
						|
    So, run() in the above example can be also written as::
 | 
						|
 | 
						|
        run("mencoder dvd://1 -o video.avi -oac copy -ovc copy",
 | 
						|
            events=[(TIMEOUT,print_ticks)], timeout=5)
 | 
						|
 | 
						|
    Use a tuple list for events if the command output requires a delicate
 | 
						|
    control over what pattern should be matched, since the tuple list is passed
 | 
						|
    to pexpect() as its pattern list, with the order of patterns preserved.
 | 
						|
 | 
						|
    Note that you should put newlines in your string if Enter is necessary.
 | 
						|
 | 
						|
    Like the example above, the responses may also contain a callback, either
 | 
						|
    a function or method.  It should accept a dictionary value 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.
 | 
						|
 | 
						|
    Like :class:`spawn`, passing *encoding* will make it work with unicode
 | 
						|
    instead of bytes. You can pass *codec_errors* to control how errors in
 | 
						|
    encoding and decoding are handled.
 | 
						|
    '''
 | 
						|
    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 isinstance(events, list):
 | 
						|
        patterns= [x for x,y in events]
 | 
						|
        responses = [y for x,y in events]
 | 
						|
    elif isinstance(events, dict):
 | 
						|
        patterns = list(events.keys())
 | 
						|
        responses = list(events.values())
 | 
						|
    else:
 | 
						|
        # This assumes EOF or TIMEOUT will eventually cause run to terminate.
 | 
						|
        patterns = None
 | 
						|
        responses = None
 | 
						|
    child_result_list = []
 | 
						|
    event_count = 0
 | 
						|
    while True:
 | 
						|
        try:
 | 
						|
            index = child.expect(patterns)
 | 
						|
            if isinstance(child.after, child.allowed_string_types):
 | 
						|
                child_result_list.append(child.before + child.after)
 | 
						|
            else:
 | 
						|
                # child.after may have been a TIMEOUT or EOF,
 | 
						|
                # which we don't want appended to the list.
 | 
						|
                child_result_list.append(child.before)
 | 
						|
            if isinstance(responses[index], child.allowed_string_types):
 | 
						|
                child.send(responses[index])
 | 
						|
            elif (isinstance(responses[index], types.FunctionType) or
 | 
						|
                  isinstance(responses[index], types.MethodType)):
 | 
						|
                callback_result = responses[index](locals())
 | 
						|
                sys.stdout.flush()
 | 
						|
                if isinstance(callback_result, child.allowed_string_types):
 | 
						|
                    child.send(callback_result)
 | 
						|
                elif callback_result:
 | 
						|
                    break
 | 
						|
            else:
 | 
						|
                raise TypeError("parameter `event' at index {index} must be "
 | 
						|
                                "a string, method, or function: {value!r}"
 | 
						|
                                .format(index=index, value=responses[index]))
 | 
						|
            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 = child.string_type().join(child_result_list)
 | 
						|
    if withexitstatus:
 | 
						|
        child.close()
 | 
						|
        return (child_result, child.exitstatus)
 | 
						|
    else:
 | 
						|
        return child_result
 | 
						|
 | 
						|
def runu(command, timeout=30, withexitstatus=False, events=None,
 | 
						|
        extra_args=None, logfile=None, cwd=None, env=None, **kwargs):
 | 
						|
    """Deprecated: pass encoding to run() instead.
 | 
						|
    """
 | 
						|
    kwargs.setdefault('encoding', 'utf-8')
 | 
						|
    return run(command, timeout=timeout, withexitstatus=withexitstatus,
 | 
						|
                events=events, extra_args=extra_args, logfile=logfile, cwd=cwd,
 | 
						|
                env=env, **kwargs)
 |