Back to index

python-cliapp  1.20120630
Functions
cliapp.runcmd Namespace Reference

Functions

def runcmd
def runcmd_unchecked
def _build_pipeline
def _run_pipeline

Function Documentation

def cliapp.runcmd._build_pipeline (   argvs,
  pipe_stdin,
  pipe_stdout,
  pipe_stderr,
  kwargs 
) [private]

Definition at line 98 of file runcmd.py.

00098 
00099 def _build_pipeline(argvs, pipe_stdin, pipe_stdout, pipe_stderr, kwargs):
00100     procs = []
00101     for i, argv in enumerate(argvs):
00102         if i == 0 and i == len(argvs) - 1:
00103             stdin = pipe_stdin
00104             stdout = pipe_stdout
00105             stderr = pipe_stderr
00106         elif i == 0:
00107             stdin = pipe_stdin
00108             stdout = subprocess.PIPE
00109             stderr = pipe_stderr
00110         elif i == len(argv) - 1:
00111             stdin = procs[-1].stdout
00112             stdout = pipe_stdout
00113             stderr = pipe_stderr
00114         else:
00115             stdin = procs[-1].stdout
00116             stdout = subprocess.PIPE
00117             stderr = pipe_stderr
00118         p = subprocess.Popen(argv, stdin=stdin, stdout=stdout, 
00119                              stderr=stderr, close_fds=True, **kwargs)
00120         procs.append(p)
00121 
00122     return procs

Here is the caller graph for this function:

def cliapp.runcmd._run_pipeline (   procs,
  feed_stdin,
  pipe_stdin,
  pipe_stdout,
  pipe_stderr 
) [private]

Definition at line 123 of file runcmd.py.

00123 
00124 def _run_pipeline(procs, feed_stdin, pipe_stdin, pipe_stdout, pipe_stderr):
00125     stdout_eof = False
00126     stderr_eof = False
00127     out = []
00128     err = []
00129     pos = 0
00130     io_size = 1024
00131     
00132     def set_nonblocking(fd):
00133         flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
00134         flags = flags | os.O_NONBLOCK
00135         fcntl.fcntl(fd, fcntl.F_SETFL, flags)
00136 
00137     if feed_stdin and pipe_stdin == subprocess.PIPE:
00138         set_nonblocking(procs[0].stdin.fileno())
00139     if pipe_stdout == subprocess.PIPE:
00140         set_nonblocking(procs[-1].stdout.fileno())
00141     if pipe_stderr == subprocess.PIPE:
00142         set_nonblocking(procs[-1].stderr.fileno())
00143     
00144     def still_running():
00145         for p in procs:
00146             p.poll()
00147         for p in procs:
00148             if p.returncode is None:
00149                 return True
00150         if pipe_stdout == subprocess.PIPE and not stdout_eof:
00151             return True
00152         if pipe_stderr == subprocess.PIPE and not stderr_eof:
00153             return True # pragma: no cover
00154         return False
00155 
00156     while still_running():
00157         rlist = []
00158         if not stdout_eof and pipe_stdout == subprocess.PIPE:
00159             rlist.append(procs[-1].stdout)
00160         if not stderr_eof and pipe_stderr == subprocess.PIPE:
00161             rlist.append(procs[-1].stderr)
00162         
00163         wlist = []
00164         if pipe_stdin == subprocess.PIPE and pos < len(feed_stdin):
00165             wlist.append(procs[0].stdin)
00166 
00167         if rlist or wlist:
00168             r, w, x = select.select(rlist, wlist, [])
00169         else:
00170             r = w = [] # pragma: no cover
00171 
00172         if procs[0].stdin in w and pos < len(feed_stdin):
00173             data = feed_stdin[pos : pos+io_size]
00174             procs[0].stdin.write(data)
00175             pos += len(data)
00176             if pos >= len(feed_stdin):
00177                 procs[0].stdin.close()
00178 
00179         if procs[-1].stdout in r:
00180             data = procs[-1].stdout.read(io_size)
00181             if data:
00182                 out.append(data)
00183             else:
00184                 stdout_eof = True
00185 
00186         if procs[-1].stderr in r:
00187             data = procs[-1].stderr.read(io_size)
00188             if data:
00189                 err.append(data)
00190             else:
00191                 stderr_eof = True
00192 
00193     return procs[-1].returncode, ''.join(out), ''.join(err)
00194 

Here is the caller graph for this function:

def cliapp.runcmd.runcmd (   argv,
  args,
  kwargs 
)
Run external command or pipeline.

Example: ``runcmd(['grep', 'foo'], ['wc', '-l'], 
                  feed_stdin='foo\nbar\n')``

Return the standard output of the command.

Raise ``cliapp.AppException`` if external command returns
non-zero exit code. ``*args`` and ``**kwargs`` are passed
onto ``subprocess.Popen``.

Definition at line 27 of file runcmd.py.

00027 
00028 def runcmd(argv, *args, **kwargs):
00029     '''Run external command or pipeline.
00030 
00031     Example: ``runcmd(['grep', 'foo'], ['wc', '-l'], 
00032                       feed_stdin='foo\nbar\n')``
00033 
00034     Return the standard output of the command.
00035     
00036     Raise ``cliapp.AppException`` if external command returns
00037     non-zero exit code. ``*args`` and ``**kwargs`` are passed
00038     onto ``subprocess.Popen``.
00039     
00040     '''
00041 
00042     if 'ignore_fail' in kwargs:
00043         ignore_fail = kwargs['ignore_fail']
00044         del kwargs['ignore_fail']
00045     else:
00046         ignore_fail = False
00047 
00048     exit, out, err = runcmd_unchecked(argv, *args, **kwargs)
00049     if exit != 0:
00050         msg = 'Command failed: %s\n%s' % (' '.join(argv), err)
00051         if ignore_fail:
00052             logging.info(msg)
00053         else:
00054             logging.error(msg)
00055             raise cliapp.AppException(msg)
00056     return out
    

Here is the call graph for this function:

def cliapp.runcmd.runcmd_unchecked (   argv,
  argvs,
  kwargs 
)
Run external command or pipeline.

Return the exit code, and contents of standard output and error
of the command.

See also ``runcmd``.

Definition at line 57 of file runcmd.py.

00057 
00058 def runcmd_unchecked(argv, *argvs, **kwargs):
00059     '''Run external command or pipeline.
00060 
00061     Return the exit code, and contents of standard output and error
00062     of the command.
00063     
00064     See also ``runcmd``.
00065     
00066     '''
00067 
00068     argvs = [argv] + list(argvs)
00069     logging.debug('run external command: %s' % repr(argvs))
00070 
00071     def pop_kwarg(name, default):
00072         if name in kwargs:
00073             value = kwargs[name]
00074             del kwargs[name]
00075             return value
00076         else:
00077             return default
00078 
00079     feed_stdin = pop_kwarg('feed_stdin', '')
00080     pipe_stdin = pop_kwarg('stdin', subprocess.PIPE)
00081     pipe_stdout = pop_kwarg('stdout', subprocess.PIPE)
00082     pipe_stderr = pop_kwarg('stderr', subprocess.PIPE)
00083 
00084     try:
00085         pipeline = _build_pipeline(argvs,
00086                                    pipe_stdin,
00087                                    pipe_stdout,
00088                                    pipe_stderr,
00089                                    kwargs)
00090         return _run_pipeline(pipeline, feed_stdin, pipe_stdin,
00091                               pipe_stdout, pipe_stderr)
00092     except OSError, e: # pragma: no cover
00093         if e.errno == errno.ENOENT and e.filename is None:
00094             e.filename = argv[0]
00095             raise e
00096         else:
00097             raise

Here is the call graph for this function:

Here is the caller graph for this function: