diff --git a/fsl/utils/callfsl.py b/fsl/utils/callfsl.py
index d86856ebebef11420d85623d357d875b8dc96fd7..1f01d34f98d1e34d0ec661025cddfaa4fdfc78d7 100644
--- a/fsl/utils/callfsl.py
+++ b/fsl/utils/callfsl.py
@@ -13,12 +13,17 @@ import               logging
 import subprocess as sp
 import os.path    as op
 
+import               deprecation
+
 from fsl.utils.platform import platform as fslplatform
 
 
 log = logging.getLogger(__name__)
 
 
+@deprecation.deprecated(deprecated_in='1.7.0',
+                        removed_in='2.0.0',
+                        details='Use fsl.utils.run.runfsl instead')
 def callFSL(*args):
     """Call a FSL command and return the result.
 
diff --git a/fsl/utils/run.py b/fsl/utils/run.py
new file mode 100644
index 0000000000000000000000000000000000000000..8ee484885c2c7244afd3874afda70174ede7762d
--- /dev/null
+++ b/fsl/utils/run.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+#
+# run.py - Functions for running shell commands
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+"""This module provides some functions for running shell commands.
+
+.. autosummary::
+   :nosignatures:
+
+   run
+   runfsl
+   fslsub
+"""
+
+
+import               logging
+import subprocess as sp
+import os.path    as op
+
+from fsl.utils.platform import platform as fslplatform
+
+
+log = logging.getLogger(__name__)
+
+
+def run(*args):
+    """Call a command and return its output.  You can pass the command and
+    arguments as a single string, or as an unpacked sequence.
+    """
+
+    # If we've been given a single argument,
+    # assume it is a string containing the
+    # command and its arguments. Otherwise,
+    # assume it is a sequence containing
+    # separate command and arguments.
+    if len(args) == 1:
+        args = args[0].split()
+
+    args = list(args)
+
+    log.debug('run: {}'.format(' '.join(args)))
+
+    result = sp.check_output(args).decode('utf-8').strip()
+
+    log.debug('result: {}'.format(result))
+
+    return result
+
+
+def runfsl(*args):
+    """Call a FSL command and return its output. This function simply prepends
+    $FSLDIR/bin/ to the command before passing it to :func:`run`.
+    """
+
+    if fslplatform.fsldir is None:
+        raise RuntimeError('$FSLDIR is not set - FSL cannot be found!')
+
+    if len(args) == 1:
+        args = args[0].split()
+
+    args    = list(args)
+    args[0] = op.join(fslplatform.fsldir, 'bin', args[0])
+
+    return run(*args)
+
+
+def fslsub(*args):
+    """Not implemented yet. """
+    raise NotImplementedError('')