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
|
||||||
from .spawn import Spawn as spawn
|
from .spawn import Spawn as spawn
|
||||||
|
from .spawn import run
|
||||||
|
|
||||||
__all__ = ['split_command_line', 'join_args', 'ExceptionPexpect', 'EOF', 'TIMEOUT',
|
__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 shutil
|
||||||
import re
|
import re
|
||||||
import traceback
|
import traceback
|
||||||
|
import types
|
||||||
|
|
||||||
import pywintypes
|
import pywintypes
|
||||||
import win32process
|
import win32process
|
||||||
@ -80,10 +81,117 @@ import winerror
|
|||||||
import win32pipe
|
import win32pipe
|
||||||
import socket
|
import socket
|
||||||
|
|
||||||
from wexpect_util import ExceptionPexpect
|
from .wexpect_util import ExceptionPexpect
|
||||||
from wexpect_util import EOF
|
from .wexpect_util import EOF
|
||||||
from wexpect_util import TIMEOUT
|
from .wexpect_util import TIMEOUT
|
||||||
from wexpect_util import split_command_line
|
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:
|
class Spawn:
|
||||||
@ -171,6 +279,7 @@ class Spawn:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self.terminate()
|
self.terminate()
|
||||||
|
self.disconnect_from_child()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -394,6 +503,10 @@ class Spawn:
|
|||||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
self.sock.connect((host, port))
|
self.sock.connect((host, port))
|
||||||
|
|
||||||
|
def disconnect_from_child(self):
|
||||||
|
if self.sock:
|
||||||
|
self.sock.close()
|
||||||
|
|
||||||
|
|
||||||
def startChild(self, args, env):
|
def startChild(self, args, env):
|
||||||
si = win32process.GetStartupInfo()
|
si = win32process.GetStartupInfo()
|
||||||
@ -434,8 +547,6 @@ class Spawn:
|
|||||||
f"wexpect.ConsoleReaderSocket(wexpect.join_args({args}), {pid}, port=4321);"
|
f"wexpect.ConsoleReaderSocket(wexpect.join_args({args}), {pid}, port=4321);"
|
||||||
)
|
)
|
||||||
|
|
||||||
print(commandLine)
|
|
||||||
|
|
||||||
self.conproc, _, conpid, __otid = win32process.CreateProcess(None, commandLine, None, None, False,
|
self.conproc, _, conpid, __otid = win32process.CreateProcess(None, commandLine, None, None, False,
|
||||||
win32process.CREATE_NEW_CONSOLE, None, None, si)
|
win32process.CREATE_NEW_CONSOLE, None, None, si)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user