# execute

Execute commands and scripts with a flexible builder pattern.

```rhai
execute(command_or_script: &str) -> Executor
```

The `Executor` builder provides a unified interface for running both single-line commands and multi-line scripts. Scripts (containing newlines) are automatically handled by writing to temporary files and executing them appropriately for your platform.

## Methods

### `.silent() -> Executor`

Suppress output - don't print stdout/stderr to console. Output is still captured and available in the result.

Default: `false` (output is displayed)

### `.ignore_error() -> Executor`

Don't throw an error on non-zero exit codes. The result will have `success: false` but won't raise an exception.

Default: `false` (errors are thrown)

### `.log() -> Executor`

Enable execution logging - prints execution start, completion status, and any errors.

Default: `false` (no logging)

### `.timeout(seconds: u64) -> Executor`

Set a timeout in seconds. If the command takes longer, it will be terminated.

Default: `None` (no timeout)

### `.env(key: &str, value: &str) -> Executor`

Add an environment variable for this execution. Can be called multiple times. These variables are added to the process environment without clearing existing ones.

### `.run() -> CommandResult`

Execute the command or script with all configured options. Returns a `CommandResult` object.

## CommandResult Properties

- `.stdout` - String containing standard output
- `.stderr` - String containing standard error  
- `.success` - Boolean indicating if exit code was 0
- `.code` - Integer exit code

## Examples

### Simple command

```rhai
let result = execute("hostname").run()?;
print(`Host: ${result.stdout}`);
```

### Command with output suppressed

```rhai
let result = execute("npm install")
    .silent()
    .run()?;
if result.success {
    print("Installation successful");
}
```

### Command that might fail

```rhai
let result = execute("test -f /tmp/file")
    .ignore_error()
    .run()?;
if result.success {
    print("File exists");
} else {
    print("File not found");
}
```

### Multi-line script

Scripts (containing newlines) are automatically written to a temporary file and executed:

```rhai
let script = `
    echo "Starting build..."
    npm run build
    echo "Build complete"
`;

let result = execute(script)
    .log()
    .run()?;
print(result.stdout);
```

### Script with bash commands

```rhai
let result = execute(`
    if [ -d "node_modules" ]; then
        echo "Dependencies already installed"
    else
        npm install
    fi
`).run()?;
```

### Command with environment variables

```rhai
let result = execute("echo $MY_VAR")
    .env("MY_VAR", "hello world")
    .run()?;
print(result.stdout);
```

### Command with timeout

```rhai
let result = execute("sleep 100")
    .timeout(5)  // Kill after 5 seconds
    .ignore_error()
    .run()?;
if !result.success {
    print("Command timed out");
}
```

### Combining multiple options

```rhai
let result = execute("make build")
    .env("BUILD_ENV", "production")
    .log()
    .timeout(300)  // 5 minute timeout
    .run()?;

if result.success {
    print("Build successful");
    print(result.stdout);
} else {
    print("Build failed");
    print(result.stderr);
}
```

## Script Handling

### Automatic Script Detection

If your command contains newlines, it's treated as a script:

```rhai
// This is a command (single line)
execute("ls -la").run()?;

// This is a script (multiple lines)
execute(`
    ls -la
    pwd
    echo "done"
`).run()?;
```

### Script Execution

- **Multiline scripts are automatically written to temporary files**
- Scripts are executed with appropriate interpreters:
  - **Unix/Linux/macOS**: `/bin/bash -e` (exits on first error)
  - **Windows**: `cmd.exe /c`
- Temporary files are automatically cleaned up after execution

### Shebang Support

If your script includes a shebang, it will be respected:

```rhai
let result = execute(`
    #!/usr/bin/env python3
    print("Hello from Python")
`).run()?;
```

Without a shebang, bash is used by default on Unix-like systems.

## Behavior

### Output Capture

By default, command output is displayed in real-time **and** captured:

```rhai
let result = execute("echo hello").run()?;
// Output: "hello" (printed to console)
// result.stdout contains: "hello\n"
```

With `.silent()`, output is only captured:

```rhai
let result = execute("echo hello").silent().run()?;
// No output to console
// result.stdout contains: "hello\n"
```

### Error Handling

By default, non-zero exit codes throw errors:

```rhai
execute("exit 1").run()?;  // Throws error
```

With `.ignore_error()`, errors are returned as result:

```rhai
let result = execute("exit 1").ignore_error().run()?;
// No exception thrown
// result.success is false
// result.code is 1
```

### Exit Codes

- `0` = success
- Any other value = failure
- The code is available as `result.code`

## Platform-Specific Notes

- **Commands vs Scripts**: Single-line commands are parsed and executed directly. Multi-line scripts are written to temporary files.
- **Windows**: Scripts are executed with `cmd.exe /c`. Commands are executed directly via CreateProcess.
- **Unix/Linux/macOS**: Scripts are executed with `/bin/bash -e`. Commands are executed via fork/exec.
