cement.utils.shell

Common Shell Utilities.

class cement.utils.shell.Prompt(text: str | None = None, *args: Any, **kw: Any)[source]

Bases: MetaMixin

A wrapper around input whose purpose is to limit the redundent tasks of gather usr input. Can be used in several ways depending on the use case (simple input, options, and numbered selection).

Parameters:

text (str) – The text displayed at the input prompt.

Example

Simple prompt to halt operations and wait for user to hit enter:

p = shell.Prompt("Press Enter To Continue", default='ENTER')
$ python myapp.py
Press Enter To Continue

$

Provide a numbered list for longer selections:

p = Prompt("Where do you live?",
        options=[
            'San Antonio, TX',
            'Austin, TX',
            'Dallas, TX',
            'Houston, TX',
            ],
        numbered = True,
        )
Where do you live?

1: San Antonio, TX
2: Austin, TX
3: Dallas, TX
4: Houston, TX

Enter the number for your selection:

Create a more complex prompt, and process the input from the user:

class MyPrompt(Prompt):
    class Meta:
        text = "Do you agree to the terms?"
        options = ['Yes', 'no', 'maybe-so']
        options_separator = '|'
        default = 'no'
        clear = True
        max_attempts = 99

    def process_input(self):
        if self.input.lower() == 'yes':
            # do something crazy
            pass
        else:
            # don't do anything... maybe exit?
            print("User doesn't agree! I'm outa here")
            sys.exit(1)

MyPrompt()
$ python myapp.py
[TERMINAL CLEAR]

Do you agree to the terms? [Yes|no|maybe-so] no
User doesn't agree! I'm outa here

$ echo $?

$ 1
class Meta[source]

Bases: object

Optional meta-data (can also be passed as keyword arguments to the parent class).

auto: bool = True

Whether or not to automatically prompt() the user once the class is instantiated.

case_insensitive: bool = True

Whether to treat user input as case insensitive (only used to compare user input with available options).

clear: bool = False

Whether or not to clear the terminal when prompting the user.

clear_command: str = 'clear'

Command to issue when clearing the terminal.

default: str | None = None

A default value to use if the user doesn’t provide any input

max_attempts: int = 10

Max attempts to get proper input from the user before giving up.

max_attempts_exception: bool = True

Raise an exception when max_attempts is hit? If not, Prompt passes the input through as None.

numbered: bool = False

Display options in a numbered list, where the user can enter a number. Useful for long selections.

options: dict | None = None

Options to provide to the user. If set, the input must match one of the items in the options selection.

options_separator: str = ','

Separator to use within the option selection (non-numbered)

selection_text: str = 'Enter the number for your selection:'

The text to display along with the numbered selection for user input.

suppress: bool = False

Suppress user input (use getpass.getpass instead of builtins.input. Default: False.

text: str = 'Tell me someting interesting:'

The text that is displayed to prompt the user

process_input() None[source]

Does not do anything. Is intended to be used in a sub-class to handle user input after it is prompted.

prompt() str | None[source]

Prompt the user, and store their input as self.input.

cement.utils.shell.cmd(command: str, capture: bool = True, *args: Any, **kwargs: Any) Tuple[str, str, int] | int[source]

Wrapper around exec_cmd and exec_cmd2 depending on whether capturing output is desired. Defaults to setting the Popen shell keyword argument to True (string command rather than list of command and arguments).

Parameters:
  • command (str) – The command (and arguments) to run.

  • capture (bool) – Whether or not to capture output.

  • args – Additional arguments are passed to Popen().

  • kwargs – Additional keyword arguments are passed to Popen().

Returns:

When capture==True, returns the ``(stdout, stderror,

return_code)`` of the command.

int: When capture==False, returns only the exitcode of the

command.

Return type:

tuple

Example

from cement.utils import shell

# execute a command and capture output
stdout, stderr, exitcode = shell.cmd('echo helloworld')

# execute a command but do not capture output
exit_code = shell.cmd('echo helloworld', capture=False)
cement.utils.shell.exec_cmd(cmd_args: str | List[str], *args: Any, **kwargs: Any) Tuple[str, str, int][source]

Execute a shell call using Subprocess. All additional *args and **kwargs are passed directly to subprocess.Popen. See Subprocess for more information on the features of Popen().

Parameters:
  • cmd_args (list) – List of command line arguments.

  • args – Additional arguments are passed to Popen().

  • kwargs – Additional keyword arguments are passed to Popen().

Returns:

The (stdout, stderror, return_code) of the command.

Return type:

tuple

Example

from cement.utils import shell

stdout, stderr, exitcode = shell.exec_cmd(['echo', 'helloworld'])
cement.utils.shell.exec_cmd2(cmd_args: str | List[str], *args: Any, **kwargs: Any) int[source]

Similar to exec_cmd, however does not capture stdout, stderr (therefore allowing it to print to console). All additional *args and **kwargs are passed directly to subprocess.Popen. See Subprocess for more information on the features of Popen().

Parameters:
  • cmd_args (list) – List of command line arguments

  • args – Additional arguments are passed to Popen()

  • kwargs – Additional keyword arguments are passed to Popen()

Returns:

The integer return code of the command.

Return type:

int

Example

from cement.utils import shell

exitcode = shell.exec_cmd2(['echo', 'helloworld'])
cement.utils.shell.spawn(target: Callable, start: bool = True, join: bool = False, thread: bool = False, *args: Any, **kwargs: Any) Process | Thread[source]

Wrapper around spawn_process and spawn_thread depending on desired execution model.

Parameters:
  • target (function) – The target function to execute in the sub-process.

  • args – Additional arguments are passed to Process()

  • kwargs – Additional keyword arguments are passed to Process().

Keyword Arguments:
  • start (bool) – Call start() on the process before returning the process object.

  • join (bool) – Call join() on the process before returning the process object. Only called if start == True.

  • thread (bool) – Whether to spawn as thread instead of process.

Returns:

The process object returned by Process().

Return type:

object

Example

from cement.utils import shell

def add(a, b):
    print(a + b)

p = shell.spawn(add, args=(12, 27))
p.join()
cement.utils.shell.spawn_process(target: Callable, start: bool = True, join: bool = False, *args: Any, **kwargs: Any) Process[source]

A quick wrapper around multiprocessing.Process(). By default the start() function will be called before the spawned process object is returned. See MultiProcessing for more information on the features of Process().

Parameters:
  • target (function) – The target function to execute in the sub-process.

  • args – Additional arguments are passed to Process()

  • kwargs – Additional keyword arguments are passed to Process().

Keyword Arguments:
  • start (bool) – Call start() on the process before returning the process object.

  • join (bool) – Call join() on the process before returning the process object. Only called if start == True.

Returns:

The process object returned by Process().

Return type:

object

Example

from cement.utils import shell

def add(a, b):
    print(a + b)

p = shell.spawn_process(add, args=(12, 27))
p.join()
cement.utils.shell.spawn_thread(target: Callable, start: bool = True, join: bool = False, *args: Any, **kwargs: Any) Thread[source]

A quick wrapper around threading.Thread(). By default the start() function will be called before the spawned thread object is returned See Threading for more information on the features of Thread().

Parameters:
  • target (function) – The target function to execute in the thread.

  • args – Additional arguments are passed to Thread().

  • kwargs – Additional keyword arguments are passed to Thread().

Keyword Arguments:
  • start (bool) – Call start() on the thread before returning the thread object.

  • join (bool) – Call join() on the thread before returning the thread object. Only called if start == True.

Returns:

The thread object returned by Thread().

Return type:

object

Example

from cement.utils import shell

def add(a, b):
    print(a + b)

t = shell.spawn_thread(add, args=(12, 27))
t.join()