Package wsatools :: Module ExternalProcess
[hide private]

Module ExternalProcess

source code

Run external processes with logging of message output.

Usage

To run an external process, e.g. mkmerge, in an "sh" shell, with just error messages logged:

   import wsatools.ExternalProcess as extp
   try:
       extp.run("mkmerge -opt=1 arg")
   except ExternalProcess.Error as error:
     Logger.addExceptionMessage(error)
     raise SystemExit

However, you don't always need to do this and it is faster to not run in an shell. To avoid running the shell, supply the command as a list of strings (with just a single item if there are no arguments):

   extp.run(["mkmerge", "-opt=1", "arg"])

To disable an ExternalProcess.Error exception from being raised if any output is sent to stdErr (i.e. there is an error), just issue this keyword argument:

   raiseOnError=False

This is important for certain CASU programs, for example, that send normal output to stdErr. In this case, stderr is redirected to stdout. Note that ExternalProcess will always raise OSError exceptions when they occur irrespective of this setting.

Turn on various run() options to enhance logging features. The full log as a list of lines is always returned, but doesn't need to be assigned to a variable. If you wish to inspect the program's terminal output, either do:

   output = extp.run("mkmerge -opt=1 arg")

or:

   for line in extp.run("mkmerge -opt=1 arg"):
       Logger.addMessage(line)

The output is always stripped. To get iterable raw output in a direct replacement for os.popen() use the out() method. However, this should only be used when output to stderr does not need to be monitored for exception purposes:

   for line in extp.out("ls"):
       Logger.addMessage(line)

To add/change any environment variables for just this run of the command, issue this keyword argument:

   env={"ENV_VARIABLE": "value", ...}

If you want to parse return codes then both parseStdOut and raiseOnError must be set to False, or else access subprocess.Popen directly. In general, it's better to parse stdErr than return codes, since it contains more information and if a command fails then it generally sends something to stdErr anyway. However, this does depend on your particular command.


Author: R.S. Collins

Organization: WFAU, IfA, University of Edinburgh

Contributors: I.A. Bond, E. Sutorius

Note: Always try to replace most standard shell commands, e.g. ls, rm, mv, cp, chmod etc. with shutil/glob/os equivalents instead of using this module.

To Do: If we really want to be pedantic we should enclose the Popen call in a with-block, e.g. "with Popen() as proc:".

Classes [hide private]
  Error
Exception thrown if some problem occurs when running the external program, e.g.
Functions [hide private]
file
out(command, stdIn='', cwd=None, env=None, close_fds=True, isVerbose=True)
Straight replacement for iterative parsing of os.popen(), it's just run() with a simplified interface, so see this function for description.
source code
list(str) or file or int
run(command, stdIn='', raiseOnError=True, parseStdOut=True, cwd=None, env=None, close_fds=True, isVerbose=True, _isIterable=False, ignoreMsgs=None)
Run the given external program.
source code
Variables [hide private]
  __package__ = 'wsatools'
Function Details [hide private]

out(command, stdIn='', cwd=None, env=None, close_fds=True, isVerbose=True)

source code 

Straight replacement for iterative parsing of os.popen(), it's just run() with a simplified interface, so see this function for description.

Returns: file
Iterable file object for stdout.

Note: This method cannot raise exceptions if there is output to stdErr, so you should always use run() if this is required.

run(command, stdIn='', raiseOnError=True, parseStdOut=True, cwd=None, env=None, close_fds=True, isVerbose=True, _isIterable=False, ignoreMsgs=None)

source code 

Run the given external program. Unless overridden, an exception is thrown on error and the output is logged.

Parameters:
  • command (str or list(str)) - Command string to execute. Use a single string with all arguments to run in shell, use a list of the command with arguments as separate elements to not run in a shell (faster if shell not needed).
  • stdIn (str) - Optionally supply some input for stdin.
  • raiseOnError (bool) - If True, if the external process sends anything to stdErr then an exception is raised and the complete programme is logged. Otherwise, stdErr is just always redirected to stdOut.
  • parseStdOut (bool) - If True, stdout is captured, not print to screen, and returned by this function, otherwise stdout is left alone and will be sent to terminal as normal.
  • cwd (str) - Run the external process with this directory as its working directory.
  • env (dict(str:str)) - Environment variables for the external process.
  • close_fds (bool) - If True, close all open file-like objects before executing external process.
  • isVerbose (bool) - If False, don't log the full command that was executed, even when Logger is in verbose mode.
  • _isIterable (bool) - Return an iterable stdout. NB: Use the out() function instead of this option.
  • ignoreMsgs (list(str)) - List of strings that if they appear in stderr should override the raiseOnError if it is set to True.
Returns: list(str) or file or int
Messages sent to stdout if parsed, otherwise an iterable file object for stdout if _isIterable, else a return a code.