# Run Shell Commands Imperatively

While `useShell()` runs a command on a fixed interval, `runShell()` executes it once when called. Use it for button clicks, event-driven actions, or when you need to post-process output before rendering.

## Declare the command

As with `useShell`, declare the command in `fluxlay.yaml`.

```yaml title="fluxlay.yaml"
shell:
  weather:
    run: curl -s "https://wttr.in/?format=%t"
    reason: Fetch the current temperature.
    required:
      - curl
```

## Run on button click

```tsx
import { useState } from "react";
import { runShell } from "@fluxlay/react";

function RefreshButton() {
  const [temp, setTemp] = useState<string>("");

  const handleClick = async () => {
    const result = await runShell("weather");
    setTemp(result.stdout.trim());
  };

  return <button onClick={handleClick}>Refresh {temp && `: ${temp}`}</button>;
}
```

## Post-process output before rendering

```tsx
async function fetchProcesses() {
  const { stdout } = await runShell("ps-aux");
  return stdout
    .split("\n")
    .slice(1, 11) // top 10
    .map(line => line.trim());
}
```

## When to use which

| Scenario                                       | Recommended |
| ---------------------------------------------- | ----------- |
| Auto-refresh in a terminal at a fixed interval | `useShell`  |
| Event-driven (button click, etc.)              | `runShell`  |
| Parse output as JSON before using              | `runShell`  |
| Filter or transform values before rendering    | `runShell`  |

## Notes

- Returns `Promise<ShellResult>` with `{ stdout, stderr, statusCode, success, signal }`. Check `success` (or `statusCode === 0`) before using `stdout`.
- The command ID must be declared in the `shell` section of `fluxlay.yaml`. Unknown IDs throw an error.
- Pass `columns` / `lines` to control the pseudo-terminal size (useful for tools that adapt to terminal width).

See the [runShell Reference](/en/studio/developer/reference/sdk/run-shell.md) for full API details.
