openclaw - 💡(How to fix) Fix feat(exec): configurable shell override (tools.exec.shell) [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#49931Fetched 2026-04-08 01:01:09
View on GitHub
Comments
1
Participants
2
Timeline
1
Reactions
0
Participants
Timeline (top)
commented ×1

Fix Action

Fix / Workaround

Current workarounds:

  • Write a .sh or .py script file for every non-trivial command
  • Use wsl jq -f filter.jq (write jq filters to files)
  • Use PTY mode (pty: true) to get an interactive WSL session and write commands via process

Code Example

{
  tools: {
    exec: {
      shell: "wsl bash"  // or "/usr/bin/bash", "pwsh", etc.
    }
  }
}
RAW_BUFFERClick to expand / collapse

Problem

On Windows, the exec tool hardcodes PowerShell as the shell. There's no config option to override this. For agents that need to run complex shell commands with pipes, jq, nested quoting, regex, etc., PowerShell's quoting rules make this extremely painful - especially when the command involves JSON processing or nested string literals.

WSL is widely available on Windows dev machines and provides a proper bash environment, but the only way to use it today is prefixing every command with wsl bash -c '...', which still goes through PowerShell's quote mangling before reaching bash. Piping works for simple cases (gh api ... | wsl jq ".field"), but anything with nested quotes in jq filters, select(), or string comparisons breaks.

Current workarounds:

  • Write a .sh or .py script file for every non-trivial command
  • Use wsl jq -f filter.jq (write jq filters to files)
  • Use PTY mode (pty: true) to get an interactive WSL session and write commands via process

All of these work but add significant friction for what should be one-liners in bash.

Proposal

Add a tools.exec.shell config option that lets users override the default shell for exec tool invocations.

{
  tools: {
    exec: {
      shell: "wsl bash"  // or "/usr/bin/bash", "pwsh", etc.
    }
  }
}

Design considerations

  • Security surface: The exec tool has allowlists, approvals, safe bins, and PATH restrictions. A shell override interacts with all of these. For example, safeBins trust paths like /bin and /usr/bin - do those apply inside WSL? How does the allowlist model work when the outer shell is different?
  • PATH handling: The current Windows exec merges login-shell PATH. With WSL, PATH semantics are different (Linux paths vs Windows paths, though WSL interop makes .exe files available).
  • Working directory translation: Workspace paths are Windows-style (C:\Users\...) but WSL sees /mnt/c/Users/.... The workdir parameter would need translation when the shell is WSL-based.
  • Non-WSL use cases: This could also be useful for forcing bash over zsh on macOS, or selecting between pwsh and legacy powershell on Windows.
  • Validation: Should probably validate that the configured shell exists and is executable at gateway start.

Environment

  • Windows 11, WSL2 with Ubuntu
  • OpenClaw 2026.3.13
  • Agent runs on gateway (no sandbox)

extent analysis

Fix Plan

To address the issue, we will implement the proposed tools.exec.shell config option. Here are the steps:

  • Add a new configuration option tools.exec.shell to override the default shell.
  • Update the exec tool to use the configured shell.
  • Handle security considerations, such as allowlists and PATH restrictions.
  • Implement PATH handling and working directory translation for WSL.

Example Code

// config.json
{
  "tools": {
    "exec": {
      "shell": "wsl bash"
    }
  }
}
// exec-tool.js
const config = require('./config.json');

// ...

const shell = config.tools.exec.shell || 'powershell';
const command = ` ${shell} -c '${commandToExecute}'`;

// ...

Verification

To verify the fix, run the following tests:

  • Test a simple command with the new shell configuration.
  • Test a command with pipes and jq filters.
  • Test a command with nested quotes and string literals.
  • Verify that the allowlists and PATH restrictions are still enforced.

Extra Tips

  • Make sure to validate the existence and executability of the configured shell at gateway start.
  • Consider adding additional logging and error handling for shell-related issues.
  • Document the new configuration option and its usage in the project's documentation.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING