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

# Command

Command hooks allow you to execute system commands or scripts as part of your replication workflow. This is particularly useful for running data processing scripts, triggering external processes, or performing system-level operations.

## Configuration

```yaml
- type: command
  command: ["executable", "arg1", "arg2"]  # Required: Command and arguments as array or string
  working_dir: /path/to/dir  # Optional: Directory to run the command in (default: Sling's current directory)
  print: true      # Optional: Print command output to console (default: true)
  capture: true    # Optional: Capture command output in hook result (default: true)
  timeout: 300     # Optional: Command timeout in seconds (default: no timeout)
  env:              # Optional: Environment variables for the command
    ENV_VAR1: "value1"
    ENV_VAR2: "value2"
  ssh_conn: MY_SSH  # Optional: Run the command remotely over an SSH connection
  on_failure: abort # Optional: abort/warn/quiet/skip
  id: my_id         # Optional. Will be generated. Use `log` hook with {runtime_state} to view state.
```

## Properties

| Property     | Required | Description                                                                                                                                                              |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| command      | Yes      | String or Array containing the command and its arguments                                                                                                                 |
| working\_dir | No       | Working directory (`cwd`) to run the command in. Defaults to the directory Sling is running from. Supports expressions and is created automatically if it does not exist |
| print        | No       | Whether to print command output to console (default: true)                                                                                                               |
| capture      | No       | Whether to capture command output in hook result (default: true)                                                                                                         |
| timeout      | No       | Command timeout in seconds. If 0 or not specified, no timeout is applied                                                                                                 |
| env          | No       | Map of environment variables to set for the command                                                                                                                      |
| ssh\_conn    | No       | Name of an SSH connection to execute the command on a remote host                                                                                                        |
| on\_failure  | No       | What to do if the command fails (abort/warn/quiet/skip)                                                                                                                  |

### Working Directory

By default the command inherits the directory Sling is running from, which is not always where your scripts or relative paths live. Use `working_dir` to set the command's `cwd` explicitly:

```yaml
hooks:
  pre:
    - type: command
      command: ./run-etl.sh --stream "{run.stream.name}"
      working_dir: /opt/etl/scripts
```

Notes:

* The value supports expressions, so it can be built dynamically — e.g. `working_dir: "/data/{run.stream.name}"` or `working_dir: "{env.PROJECT_DIR}/scripts"`.
* If the directory does not exist, Sling creates it before running the command.
* When combined with `ssh_conn`, the command is prefixed with `cd <working_dir> &&` on the remote host.

## Output

When the command hook executes successfully, it returns the following output that can be accessed in subsequent hooks:

```yaml
status: success  # Status of the hook execution
binary: "/path/to/executable"  # The binary that was executed
arguments: ["arg1", "arg2"]  # The arguments passed to the command
start: "2024-01-01T00:00:00Z"  # Command start time
end: "2024-01-01T00:00:01Z"  # Command end time
timeout: 300  # Only present if timeout was specified
output:  # Only present if capture: true
  stdout: "Standard output text"
  stderr: "Standard error text"
  combined: "Combined output text"
```

You can access these values in subsequent hooks using the following syntax (`jmespath`):

* `{state.hook_id.status}` - Status of the hook execution
* `{state.hook_id.binary}` - The binary that was executed
* `{state.hook_id.arguments}` - The arguments passed to the command
* `{state.hook_id.start}` - Command start time
* `{state.hook_id.end}` - Command end time
* `{state.hook_id.timeout}` - Timeout value (if specified)
* `{state.hook_id.output.stdout}` - Standard output (if capture: true)
* `{state.hook_id.output.stderr}` - Standard error (if capture: true)
* `{state.hook_id.output.combined}` - Combined output (if capture: true)

## Examples

### Run Data Processing Script

Execute a Python script to process data before replication:

```yaml
hooks:
  pre:
    - type: command
      command: python scripts/process_data.py --stream "{run.stream.name}"
      timeout: 600  # 10 minute timeout
      env:
        PYTHONPATH: "/path/to/libs"
        DATA_DIR: "{env.data_directory}"
      print: true
      on_failure: abort
```

### Run a CLI Tool from Its Own Directory

Run a custom CLI tool that expects to be invoked from its project directory (so relative paths and config files resolve correctly):

```yaml
hooks:
  pre:
    - type: command
      command: ["./my-cli", "extract", "--config", "config.yaml"]
      working_dir: /opt/my-tool
      capture: true
      print: true
      on_failure: abort
```

### System Cleanup

Clean up temporary files after processing:

```yaml
hooks:
  post:
    - type: command
      command: ["rm", "-rf", "/tmp/processed/{run.stream.name}/*"]
      on_failure: warn
```

### Run Data Quality Checks

Execute a data quality checking script and capture its output:

```yaml
hooks:
  post:
    - type: command
      command: [
        "python",
        "scripts/quality_check.py",
        "--table", "{run.object.full_name}",
        "--date", "{timestamp.date}"
      ]
      timeout: 1800  # 30 minute timeout
      capture: true
      env:
        DB_CONNECTION: "{target.connection_string}"
      on_failure: warn
```

### Conditional Command Execution

Run commands based on environment or conditions:

```yaml
hooks:
  post:
    - type: command
      if: env.PRODUCTION == "true"
      command: notify-admin --stream "{run.stream.name}" --status {run.status}
      print: true
      env:
        NOTIFY_TOKEN: "{env.notification_token}"
```

### Run Shell Script

Execute a shell script with parameters:

```yaml
hooks:
  pre:
    - type: command
      command: [
        "bash",
        "scripts/prepare_environment.sh",
        "{target.environment}",
        "{run.stream.name}"
      ]
      print: true
      capture: true
      on_failure: abort
```

### Generate Reports

Run a report generation tool after successful replication:

```yaml
hooks:
  post:
    - type: command
      if: run.status == "success"
      command: [
        "report-generator",
        "--input", "{run.object.full_name}",
        "--output", "reports/{run.stream.name}_{timestamp.date}.pdf"
      ]
      timeout: 900  # 15 minute timeout
      env:
        REPORT_TEMPLATE: "templates/standard.tpl"
        OUTPUT_DIR: "/var/reports"
```


---

# 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.slingdata.io/concepts/hooks/command.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.
