docs/versioned_docs/version-0.17.2/features/shell.mdx
import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';
Dagger Shell is the fastest way to interact with the Dagger API. Dagger Shell brings the power of pipelines to fully typed API objects while maintaining a familiar Bash-like syntax. With autocomplete for core types, modules, and functions, it makes writing and exploring Dagger pipelines smoother than ever.
Dagger Shell enables you to compose pipelines on the fly, by chaining together core Dagger primitives like Container and Directory with module-defined types and functions. It can be used inline, with scripts, or interactively. It is secure by design, as all commands execute in containers and you have complete control over what goes in or out from the host system.
Here's an example of Dagger Shell in action:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger <<EOF container | from alpine | with-exec apk add curl | with-exec -- curl -L https://dagger.io | stdout EOF ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." container | from alpine | with-exec apk add curl | with-exec -- curl -L https://dagger.io | stdout ``` </TabItem> </Tabs>Here's another, more complex example:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger <<EOF container | from cgr.dev/chainguard/wolfi-base | with-exec apk add go | with-directory /src https://github.com/golang/example#master | with-workdir /src/hello | with-exec -- go build -o hello . | file ./hello | export ./hello-from-dagger EOF ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." container | from cgr.dev/chainguard/wolfi-base | with-exec apk add go | with-directory /src https://github.com/golang/example#master | with-workdir /src/hello | with-exec -- go build -o hello . | file ./hello | export ./hello-from-dagger ``` </TabItem> </Tabs>:::note Dagger Shell allows you to execute Dagger Functions as native shell commands, using a Bash-compatible syntax. However, instead of calling a subprocess for execution, Dagger Shell directly interprets commands within the Dagger CLI and executes them in containers. This means that all your commands execute as API calls in a secure, sandboxed environment, rather than as processes with direct access to the host system. :::
Dagger Shell supports multiple ways to run commands:
<Tabs groupId="shell"> <TabItem value="Inline execution"> ```shell dagger -c 'container | from alpine | terminal' ``` </TabItem> <TabItem value="Standard input"> ```shell title="First type 'dagger' for interactive mode." echo 'container | from alpine | terminal' | dagger ``` </TabItem> <TabItem value="Script"> ```shell echo 'container | from alpine | with-exec cat /etc/os-release | stdout' > script.sh dagger script.sh ``` </TabItem> <TabItem value="Interactive REPL"> ```shell title="First type 'dagger' for interactive mode." container | from alpine | terminal ``` </TabItem> </Tabs>Dagger Shell provides extensive built-in help:
.help # Shows available commands
.help <module> # Shows description, entrypoint arguments, and available functions
.help <function> # Shows description, arguments, and return type for function
<function> | .help # Shows details on the type returned by <function>, including available functions if an object
Dagger Shell presents a virtual filesystem to the user. When Dagger Shell starts, it sets the working directory to an initial context, which defaults to the enclosing Git repository or Dagger module. The user can navigate the virtual filesystem by changing the working directory.
The initial context can be a local filesystem path or a remote filesystem. For example, dagger -m github.com/dagger/dagger/[email protected] changes the context to github.com/dagger/[email protected] and the working directory to /docs.
:::note To safeguard access to the host filesystem, the context root cannot be escaped. :::
If the working directory contains a Dagger module, that module is automatically loaded, and its Dagger Functions can be directly inspected (via .help) or invoked.
:::tip
If only the core Dagger API is needed, the -n (--no-mod) flag can be provided. This reduces the startup time because the Dagger CLI doesn't try to find and load a current module.
:::
Filesystem paths are handled differently depending on the initial context of the module loaded in Dagger Shell.
host function.Here's an example:
<Tabs groupId="shell"> <TabItem value="System shell"> ```shell dagger <<EOF github.com/dagger/dagger/modules/[email protected] | container | with-file /README.md $(host | file ./README.md) | with-exec cat /README.md | stdout EOF ``` </TabItem> <TabItem value="Dagger Shell"> ```shell title="First type 'dagger' for interactive mode." github.com/dagger/dagger/modules/[email protected] | container | with-file /README.md $(host | file ./README.md) | with-exec cat /README.md | stdout ``` </TabItem> </Tabs>While inspired by Bash, Dagger Shell introduces key differences: