# Execute (Shell & JavaScript)

Plugin allows to invoke any shell command.

Available actions:

* [exec](/plugins/exec.md#action-handler-shell-command) - execute single command
* [shell](/plugins/exec.md#action-handler-shell-script) - execute shell script
* [fn](/plugins/exec.md#action-handler-function) - execute JS function

## Action Handler: Shell Command

Invoice single shell command.

**ID:** `com.fireblink.fbl.exec`

**Aliases:**

* `fbl.exec`
* `exec`

**Example:**

```yaml
exec:
  # executable to invoke
  command: 'echo'

  # additional executable arguments, note "command" cannot have arguments in its value, just executable alias or path to it
  args:
    - 'test'

  # [optional] working directory to run command from.
  # Default value: flow's folder
  wd: <%- cwd %>

  # [optional] options
  options:
    # [optional] if provided "stdout" will be included inside assigned object to proviced "ctx" and/or "secrets" name
    stdout: true
    # [optional]  if provided "stderr" will be included inside assigned object to proviced "ctx" and/or "secrets" name
    stderr: true
    # [optional] if provided - stdout and stderr will be logged in report and printed to console
    verbose: false

  # [optional] assign execution result {code: 0-255, stdout?: string, stderr?: string }
  assignResultTo: # follows common assignment logic practicies https://fbl.fireblink.com/plugins/common#assign-to

  # [optional] push execution result {code: 0-255, stdout?: string, stderr?: string }
  pushResultTo: # follows common push logic practicies https://fbl.fireblink.com/plugins/common#push-to
```

## Action Handler: Shell Script

Invoke shell script. While it gives a more convinient way to integrate shell scripts into the flow it also makes your flow less platform agnostic.

**ID:** `com.fireblink.fbl.shell`

**Aliases:**

* `fbl.shell`
* `shell`

**Example:**

```yaml
shell:
  # shell executable
  executable: '/bin/bash'

  # script to be invoked
  script: |-
    cd /tmp
    touch test.txt

  # [optional] working directory to run script from.
  # Default value: flow's folder
  wd: <%- cwd %>

  # [optional] options
  options:
    # [optional] if provided "stdout" will be included inside assigned object to proviced "ctx" and/or "secrets" name
    stdout: true
    # [optional] if provided "stderr" will be included inside assigned object to proviced "ctx" and/or "secrets" name
    stderr: true
    # [optional] if provided - stdout and stderr will be logged in report and printed to console
    verbose: false

  # [optional] assign execution result {code: 0-255, stdout?: string, stderr?: string }
  assignResultTo: # follows common assignment logic practicies https://fbl.fireblink.com/plugins/common#assign-to

  # [optional] push execution result {code: 0-255, stdout?: string, stderr?: string }
  ushResultTo: # follows common push logic practicies https://fbl.fireblink.com/plugins/common#push-to
```

## Action Handler: Function

Allows to invoke custom JavaScript script (ES6). Script has access to all context variables:

* cwd
* ctx
* secrets
* parameters
* iteration

But also to Node.js `require` function and can interact with awailable node modules. Though, it is recomended to use fbl plugins instead.

**ID:** `com.fireblink.fbl.function`

**Aliases:**

* `fbl.function`
* `function`
* `function()`
* `fn`
* `fn()`

**Example: Direct Changes**

```yaml
# Action handler expects valid JS function content string.
#
# Note: script is wrapped into async function, so you can "await" promises inside it
# if you need to do some long running operations.
fn: |-
  ctx.isWindows = require('os').platform() === 'win32';
```

**Example: Overrides**

Alternativelly function can return object that will be used to override entire state of context and parameters fields.

```yaml
fn: |-
  return {
    cwd: '/tmp',
    ctx: {
      test: true
    }      
  }
```

```yaml
fn: |-
  return {
    secrets: {
      test: true
    },
    parameters: {
      p1: ctx.p2
    }
  }
```


---

# Agent Instructions: 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:

```
GET https://fbl.fireblink.com/plugins/exec.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
