Skip to content
Snippets Groups Projects
Commit fd39ff03 authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

Enhancements to run function - can get stderr and/or return code

parent 577cf431
No related branches found
No related tags found
No related merge requests found
...@@ -34,6 +34,13 @@ execute them. ...@@ -34,6 +34,13 @@ execute them.
""" """
class FSLNotPresent(Exception):
"""Error raised by the :func:`runfsl` function when ``$FSLDIR`` cannot
be found.
"""
pass
@contextlib.contextmanager @contextlib.contextmanager
def dryrun(*args): def dryrun(*args):
"""Context manager which causes all calls to :func:`run` to be logged but """Context manager which causes all calls to :func:`run` to be logged but
...@@ -68,11 +75,29 @@ def _prepareArgs(args): ...@@ -68,11 +75,29 @@ def _prepareArgs(args):
return list(args) return list(args)
def run(*args): def run(*args, **kwargs):
"""Call a command and return its output. You can pass the command and """Call a command and return its output. You can pass the command and
arguments as a single string, or as a regular or unpacked sequence. arguments as a single string, or as a regular or unpacked sequence.
An exception is raised if the command returns a non-zero exit code, unless
the ``returnCode`` option is set to ``True``.
:arg err: Must be passed as a keyword argument. Defaults to
``False``. If ``True``, standard error is captured and
returned.
:arg ret: Must be passed as a keyword argument. Defaults to
``False``. If ``True``, and the command's return code
is non-0, an exception is not raised.
:returns: A string containing the command's standard output. Or,
if ``err is True`` and/or ``returnCode is True``, a tuple
containing the standard output, standard error (if
``err``), and return code (if ``returnCode``).
""" """
err = kwargs.get('err', False)
ret = kwargs.get('ret', False)
args = _prepareArgs(args) args = _prepareArgs(args)
if DRY_RUN: if DRY_RUN:
...@@ -81,13 +106,30 @@ def run(*args): ...@@ -81,13 +106,30 @@ def run(*args):
log.debug('run: {}'.format(' '.join(args))) log.debug('run: {}'.format(' '.join(args)))
if DRY_RUN: if DRY_RUN:
result = '<dryrun>' stdout = '<dryrun>'
stderr = ''
else: else:
result = sp.check_output(args).decode('utf-8').strip() proc = sp.Popen(args, stdout=sp.PIPE, stderr=sp.PIPE)
stdout, stderr = proc.communicate()
retcode = proc.returncode
stdout = stdout.decode('utf-8').strip()
stderr = stderr.decode('utf-8').strip()
log.debug('stdout: {}'.format(stdout))
log.debug('stderr: {}'.format(stderr))
if not ret and (retcode != 0):
raise RuntimeError('{} returned non-zero exit code: {}'.format(
args[0], retcode))
results = [stdout]
log.debug('result: {}'.format(result)) if err: results.append(stderr)
if ret: results.append(retcode)
return result if len(results) == 1: return results[0]
else: return tuple(results)
def runfsl(*args): def runfsl(*args):
...@@ -96,7 +138,7 @@ def runfsl(*args): ...@@ -96,7 +138,7 @@ def runfsl(*args):
""" """
if fslplatform.fsldir is None: if fslplatform.fsldir is None:
raise RuntimeError('$FSLDIR is not set - FSL cannot be found!') raise FSLNotPresent('$FSLDIR is not set - FSL cannot be found!')
args = _prepareArgs(args) args = _prepareArgs(args)
args[0] = op.join(fslplatform.fsldir, 'bin', args[0]) args[0] = op.join(fslplatform.fsldir, 'bin', args[0])
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment