# !exec

The `!exec` Atmos YAML function is used to execute shell scripts and assign
the results to the sections in Atmos stack manifests.

## Usage

```yaml
var1: !exec echo 42

var2: !exec get-data.sh

var3: !exec atmos terraform output <component> -s <stack> --skip-init -- -json test_label_id

var4: !exec atmos terraform output <component> -s {{ .stack }} --skip-init -- -json test_map

var5: !exec atmos terraform output <component> -s {{ .stack }} --skip-init -- -json test_list

var6: |
  !exec
    foo=0
    for i in 1 2 3; do
      foo+=$i
    done
    echo $foo
```

You can execute inline shell scripts, scripts defined in external files, or even Atmos or Terraform commands
(e.g. `!exec atmos terraform output`).

:::warning
`!exec atmos terraform output` is just as examples to show that you can get the outputs of an Atmos component using
the `!exec` YAML function, but it's not recommended to use.
Instead, use the [`!terraform.output`](/functions/yaml/terraform.output)
YAML function. It produces the same results, correctly handles complex types (lists and maps),
has a much simpler syntax, and automatically caches the results for the same component and stack (so if you are calling
it many times on the same component in the same stack, it will execute `terraform output` only once and the stack
processing will be much faster)
:::

The result of a script execution can be a simple type (string, number, or boolean), in which case Atmos
assigns it without modification.

If the result is a complex type (list, map or object), the script must return it as a JSON-encoded string.
After receiving the JSON-encoded string, Atmos automatically decodes it into the corresponding YAML complex type.

:::info
Atmos uses the [`interp`](https://pkg.go.dev/mvdan.cc/sh/v3@v3.10.0/interp) `Go` package to execute the shell scripts
in the `!exec` YAML function.

Package `interp` implements an interpreter that executes shell programs.
It aims to support POSIX and to behave like Bash, but it does not support all of its features.
:::

:::tip
You can use [Atmos Stack Manifest Templating](/templates) in the `!exec` YAML function expressions.
Atmos processes the templates first, and then executes the `!exec` function, allowing you to provide the parameters to
the function dynamically.
:::

:::note Type-Aware Merging
Atmos supports type-aware merging of YAML functions and concrete values, allowing them to coexist in the inheritance chain without type conflicts.
See the full explanation: [YAML Function Merging](/reference/yaml-function-merging)
:::
