mirror of
https://github.com/clearml/wexpect-venv
synced 2025-06-26 18:15:52 +00:00
[ADD] run function
This commit is contained in:
parent
c7a4e092c8
commit
ba20b3f0d8
@ -11,6 +11,7 @@ from .console_reader import ConsoleReaderPipe
|
||||
|
||||
from .spawn import Spawn
|
||||
from .spawn import Spawn as spawn
|
||||
from .spawn import run
|
||||
|
||||
__all__ = ['split_command_line', 'join_args', 'ExceptionPexpect', 'EOF', 'TIMEOUT',
|
||||
'ConsoleReaderSocket', 'ConsoleReaderPipe', 'spawn', 'Spawn']
|
||||
'ConsoleReaderSocket', 'ConsoleReaderPipe', 'spawn', 'Spawn', 'run']
|
||||
|
123
wexpect/spawn.py
123
wexpect/spawn.py
@ -70,6 +70,7 @@ import os
|
||||
import shutil
|
||||
import re
|
||||
import traceback
|
||||
import types
|
||||
|
||||
import pywintypes
|
||||
import win32process
|
||||
@ -80,10 +81,117 @@ import winerror
|
||||
import win32pipe
|
||||
import socket
|
||||
|
||||
from wexpect_util import ExceptionPexpect
|
||||
from wexpect_util import EOF
|
||||
from wexpect_util import TIMEOUT
|
||||
from wexpect_util import split_command_line
|
||||
from .wexpect_util import ExceptionPexpect
|
||||
from .wexpect_util import EOF
|
||||
from .wexpect_util import TIMEOUT
|
||||
from .wexpect_util import split_command_line
|
||||
|
||||
|
||||
def run (command, timeout=-1, withexitstatus=False, events=None, extra_args=None, logfile=None, cwd=None, env=None):
|
||||
|
||||
"""
|
||||
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. """
|
||||
|
||||
if timeout == -1:
|
||||
child = Spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env)
|
||||
else:
|
||||
child = Spawn(command, timeout=timeout, maxread=2000, logfile=logfile, cwd=cwd, env=env)
|
||||
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:
|
||||
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.close()
|
||||
return (child_result, child.exitstatus)
|
||||
else:
|
||||
return child_result
|
||||
|
||||
|
||||
class Spawn:
|
||||
@ -171,6 +279,7 @@ class Spawn:
|
||||
|
||||
try:
|
||||
self.terminate()
|
||||
self.disconnect_from_child()
|
||||
except:
|
||||
pass
|
||||
|
||||
@ -394,6 +503,10 @@ class Spawn:
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.sock.connect((host, port))
|
||||
|
||||
def disconnect_from_child(self):
|
||||
if self.sock:
|
||||
self.sock.close()
|
||||
|
||||
|
||||
def startChild(self, args, env):
|
||||
si = win32process.GetStartupInfo()
|
||||
@ -434,8 +547,6 @@ class Spawn:
|
||||
f"wexpect.ConsoleReaderSocket(wexpect.join_args({args}), {pid}, port=4321);"
|
||||
)
|
||||
|
||||
print(commandLine)
|
||||
|
||||
self.conproc, _, conpid, __otid = win32process.CreateProcess(None, commandLine, None, None, False,
|
||||
win32process.CREATE_NEW_CONSOLE, None, None, si)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user