about summary refs log tree commit diff stats
path: root/ranger/ext/spawn.py
blob: ffb4d94b653b1f708edba013d498f79ecf1eb0ea (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# This file is part of ranger, the console file manager.
# License: GNU GPL version 3, see the file "AUTHORS" for details.

from __future__ import (absolute_import, print_function)

from os import devnull
from subprocess import Popen, PIPE, CalledProcessError
ENCODING = 'utf-8'


def check_output(popenargs, **kwargs):
    """Runs a program, waits for its termination and returns its output

    This function is functionally identical to python 2.7's subprocess.check_output,
    but is favored due to python 2.6 compatibility.

    Will be run through a shell if `popenargs` is a string, otherwise the command
    is executed directly.

    The keyword argument `decode` determines if the output shall be decoded
    with the encoding UTF-8.

    Further keyword arguments are passed to Popen.
    """

    do_decode = kwargs.pop('decode', True)
    kwargs.setdefault('stdout', PIPE)
    kwargs.setdefault('shell', isinstance(popenargs, str))

    if 'stderr' in kwargs:
        process = Popen(popenargs, **kwargs)
        stdout, _ = process.communicate()
    else:
        with open(devnull, mode='w') as fd_devnull:
            process = Popen(popenargs, stderr=fd_devnull, **kwargs)
            stdout, _ = process.communicate()

    if process.returncode != 0:
        error = CalledProcessError(process.returncode, popenargs)
        error.output = stdout
        raise error

    if do_decode and stdout is not None:
        stdout = stdout.decode(ENCODING)

    return stdout


def spawn(*popenargs, **kwargs):
    """Runs a program, waits for its termination and returns its stdout

    This function is similar to python 2.7's subprocess.check_output,
    but is favored due to python 2.6 compatibility.

    The arguments may be:

        spawn(string)
        spawn(command, arg1, arg2...)
        spawn([command, arg1, arg2])

    Will be run through a shell if `popenargs` is a string, otherwise the command
    is executed directly.

    The keyword argument `decode` determines if the output shall be decoded
    with the encoding UTF-8.

    Further keyword arguments are passed to Popen.
    """
    if len(popenargs) == 1:
        return check_output(popenargs[0], **kwargs)
    return check_output(list(popenargs), **kwargs)