# geni exec bash (/cli/exec/bash)



```sh
geni exec bash [flags] -- <command>
```

Runs a bash command with one or more credentials' values made available as environment variables. Use it for anything you'd run in a shell — `curl`, `git`, `gh`, `aws`, language CLIs, ad-hoc scripts.

## Synopsis [#synopsis]

```sh
geni exec bash \
  --cred cred_01HX… --reason "Validating Slack token" \
  -- 'curl -H "Authorization: Bearer $SLACK_ACCESS_TOKEN" https://slack.com/api/auth.test'
```

| Flag                | Notes                                                                                                                            |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `--cred <id>`       | Credential to make available. Repeat for each credential the command needs.                                                      |
| `--reason <text>`   | Why this credential is being used. Recorded in your audit log. Required per cred.                                                |
| `-f, --file <path>` | Read the command from a file instead of after `--`. Pass `-` to read from stdin. Preferred for anything with quotes or newlines. |
| `--cwd <path>`      | Working directory. Defaults to the current directory.                                                                            |
| `--`                | Separator. Everything after is the bash command.                                                                                 |

## What env vars get set [#what-env-vars-get-set]

For each credential you pass with `--cred`, `geni` exposes its values as environment variables your command can read. To see the exact env var names a credential will set, run [`geni credential get <id>`](/cli/credential/get) or check the operation's reference docs.

## Output [#output]

```
$ geni exec bash --cred cred_01HX… --reason "..." -- 'curl -s https://api.example.com/'
{"data":[...]}
```

stdout, stderr, and the exit code are forwarded transparently — same as running the command yourself.

Any literal occurrence of a secret value in the output is replaced inline with `[REDACTED:cred_…]` so tokens never appear in logs or transcripts.

## Examples [#examples]

### Simple curl [#simple-curl]

```sh
geni exec bash \
  --cred cred_01HX7AB --reason "Listing Salesforce contacts" \
  -- 'curl -s -H "Authorization: Bearer $SALESFORCE_ACCESS_TOKEN_01HX7AB" "$SALESFORCE_INSTANCE_URL_01HX7AB/services/data/v59.0/sobjects/Contact"'
```

### Multiple credentials in one call [#multiple-credentials-in-one-call]

```sh
geni exec bash \
  --cred cred_slackA --reason "Posting to #engineering" \
  --cred cred_slackB --reason "Posting to #marketing" \
  -- 'curl -s -X POST https://slack.com/api/chat.postMessage \
        -H "Authorization: Bearer $SLACK_ACCESS_TOKEN_SLACKA" \
        -d "channel=#engineering&text=hi"'
```

### A multi-line script with nested quotes (`--file`) [#a-multi-line-script-with-nested-quotes---file]

Fighting shell quoting across several layers (a `curl` piped into `jq` or `python`, with its own quotes) is the most common way an `exec bash` call breaks. Write the script to a file and point `--file` at it — no quoting layers:

```sh
cat > /tmp/q.sh <<'EOF'
curl -s -H "Authorization: Bearer $QUICKBOOKS_ACCESS_TOKEN_01HX" \
  "$QUICKBOOKS_BASE_URL/v3/company/$REALM/query?query=select%20*%20from%20Account" \
  | jq '.QueryResponse.Account[] | {name: .Name, balance: .CurrentBalance}'
EOF

geni exec bash --cred cred_01HX --reason "Reading QuickBooks accounts" --file /tmp/q.sh
```

Or stream the script over stdin with `--file -`:

```sh
geni exec bash --cred cred_01HX --reason "Reading QuickBooks accounts" --file - <<'EOF'
curl -s "$QUICKBOOKS_BASE_URL/..." | jq '.QueryResponse.Account | length'
EOF
```
