> For the complete documentation index, see [llms.txt](https://docs.builtoncement.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.builtoncement.com/utilities/shell.md).

# Shell

## Introduction to the Shell Utilities <a href="#introduction-to-the-output-interface" id="introduction-to-the-output-interface"></a>

Cement includes a [Shell Utility Module](https://cement.readthedocs.io/en/3.0/api/utils/shell/) with helpers for common tasks related to executing commands, spawning subprocesses/threads, and other tasks.

**API References:**

* [Cement Shell Utility Module](https://cement.readthedocs.io/en/3.0/api/utils/shell/)

## Prompting User Input

Requesting input from the user is straight forward, however we've included the [`shell.Prompt`](https://cement.readthedocs.io/en/3.0/api/utils/shell/#cement.utils.shell.Prompt) utility to expand beyond just a simple one-dimensional input response.

{% tabs %}
{% tab title="Example: User Input Prompts" %}
{% code title="example.py" %}

```python
from cement import shell

### simple user response prompt

p = shell.Prompt("Press Enter To Continue", default='ENTER')
res = p.prompt()

### provide a numbered list for longer selections

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

### Create a more complex prompt, and process the input

class MyPrompt(shell.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")

p = MyPrompt()
```

{% endcode %}
{% endtab %}

{% tab title="cli" %}

```
$ python example.py

### simple user response prompt

Press Enter To Continue

### provide a numbered list for longer selections

Where do you live?

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

Enter the number for your selection: 1

### Create a more complex prompt, and process the input

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

{% endtab %}
{% endtabs %}

## Executing Commands

Shell commands can be executed via the `shell.cmd()` function in two ways; by capturing STDOUT/STDERR and exit code, or just the exit code and letting STDOUT/STDERR print to console normally.

{% tabs %}
{% tab title="Example: Executing Commands" %}

```python
from cement import shell

### execute command and capture output
out, err, code = shell.cmd('echo helloworld')

### execute command with output to console
code = shell.cmd('echo helloworld', capture=False)
```

{% endtab %}
{% endtabs %}

## Spawning Processes and Threads

Spawning processes and threads is easy via the `shell.spawn()` helper.

{% tabs %}
{% tab title="Example: Spawning Processes and Threads" %}

```python
from cement import shell

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

### spawn a process
p = shell.spawn(add, args=(12, 27))
p.join()

### spawn a thread
t = shell.spawn(add, args=(12, 27), thread=True)
t.join()
```

{% endtab %}
{% endtabs %}

See the [multiprocessing](https://docs.python.org/3/library/multiprocessing.html) and [threading](https://docs.python.org/3/library/threading.html) modules in the Python standard library for more information on working with processes and threads.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.builtoncement.com/utilities/shell.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
