Skip to content

docs: add -s -- flags to curl|bash install to prevent stdin consumption#73830

Closed
unn-Known1 wants to merge 1 commit into
openclaw:mainfrom
unn-Known1:fix/issue-73814-stdin-pipe-fix
Closed

docs: add -s -- flags to curl|bash install to prevent stdin consumption#73830
unn-Known1 wants to merge 1 commit into
openclaw:mainfrom
unn-Known1:fix/issue-73814-stdin-pipe-fix

Conversation

@unn-Known1

Copy link
Copy Markdown

Summary

Fixes #73814

The install.sh script uses interactive prompts (via gum) that consume stdin. When the script is piped via curl | bash, stdin is occupied by the script stream, causing the prompts to consume portions of the script itself, resulting in truncated function names and indefinite hangs.

Solution

Added -s -- flags to the install command in the getting started documentation:

curl -fsSL https://openclaw.ai/install.sh | bash -s --

The -s -- flags prevent the bash subshell from allowing stdin to reach the script interactive prompts. This is a standard pattern for piped installation scripts.

Testing

  • Markdown linting passed (0 errors)
  • Documentation renders correctly

Disclosure

This contribution was developed with AI assistance.

…onsumption

Fixes #73814

The install.sh script uses interactive prompts (via gum) that consume stdin.
When the script is piped via 'curl | bash', stdin is occupied by the script
stream, causing the prompts to consume portions of the script itself,
resulting in truncated function names and indefinite hangs.

Adding '-s --' flags prevents the bash subshell from allowing stdin to
reach the script's interactive prompts. This is a standard pattern for
piped installation scripts.
@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge.

Summary
The PR changes the Getting Started macOS/Linux installer command to curl ... | bash -s -- and adds a note claiming those flags prevent stdin consumption.

Reproducibility: yes. for the PR's claimed fix: a focused pipe smoke shows a child process can still consume the next script line under both bash and bash -s --. The full linked WSL2 hosted-installer hang was not executed.

Real behavior proof
Not applicable: Real behavior proof is not required because this PR only changes files under docs/.

Next step before merge
A repair worker can address the concrete false docs claim and, if pursuing the linked installer bug, move the fix into the installer stdin handoff with focused coverage.

Security
Cleared: The diff is documentation-only and does not change executable code, dependency resolution, CI permissions, release logic, package metadata, or secret handling.

Review findings

  • [P1] Remove the false stdin guarantee — docs/start/getting-started.md:48
Review details

Best possible solution:

Harden installer subprocess stdin handling or document a tested caller pattern, then update all public install examples consistently with focused installer smoke coverage.

Do we have a high-confidence way to reproduce the issue?

Yes for the PR's claimed fix: a focused pipe smoke shows a child process can still consume the next script line under both bash and bash -s --. The full linked WSL2 hosted-installer hang was not executed.

Is this the best way to solve the issue?

No. bash -s -- is useful for passing arguments to a piped script, but it is not stdin isolation; installer-side /dev/tty handling or a tested alternate caller pattern is safer.

Full review comments:

Overall correctness: patch is incorrect
Overall confidence: 0.93

Acceptance criteria:

  • pnpm docs:list
  • git diff --check
  • node scripts/run-vitest.mjs test/scripts/install-sh.test.ts
  • Crabbox/Testbox installer smoke for the default piped installer path if installer runtime behavior changes

What I checked:

  • PR diff adds the disputed note: The proposed patch changes only docs/start/getting-started.md, replacing the default installer pipe with bash -s -- and adding a note that those flags prevent stdin consumption when piped via curl | bash. (docs/start/getting-started.md:48, d4439a0cc678)
  • Focused pipe smoke without flags: A child bash -c 'read ...' consumed the next script line and printed child-read=echo after-parent-line under plain bash.
  • Focused pipe smoke with bash -s --: The same child process also consumed the next script line under bash -s --, producing the same child-read=echo after-parent-line output.
  • Current Getting Started docs still show the original pipe: Current main still documents curl -fsSL https://openclaw.ai/install.sh | bash for the macOS/Linux quick setup path. Public docs: docs/start/getting-started.md. (docs/start/getting-started.md:32, 48b4e5b3614f)
  • Installer source still has a subprocess stdin handoff: Prompt helpers use /dev/tty, but run_bootstrap_onboarding_if_needed still invokes "$claw" onboard without redirecting stdin; a later onboarding path explicitly does exec </dev/tty before handoff. (scripts/install.sh:2587, 48b4e5b3614f)
  • Install reference docs would remain inconsistent: The install reference still documents raw curl ... | bash as the default install command and reserves bash -s -- for option-passing examples. Public docs: docs/install/installer.md. (docs/install/installer.md:23, 48b4e5b3614f)

Likely related people:

  • steipete: Recent remote history for scripts/install.sh includes installer hardening, website installer sync, and install proof work, and local blame routes the current stdin handoff area through Peter Steinberger. (role: recent installer area contributor; confidence: high; commits: e60928d13c71, 2796eebb03d3, 66a8ff178c79; files: scripts/install.sh, scripts/docker/install-sh-smoke/run.sh, test/scripts/install-sh.test.ts)
  • vincentkoc: Recent docs history shows install and Getting Started documentation normalization and restructuring on the affected docs surfaces. (role: adjacent install docs contributor; confidence: medium; commits: 627c19c5cbbe, 2777b089b53f, 78e4f5188af5; files: docs/start/getting-started.md, docs/install/index.md, docs/install/installer.md)

Remaining risk / open question:

  • The full WSL2 Ubuntu 24.04 hosted-installer hang was not rerun in this read-only review, so the exact original symptom still needs real installer proof after a proposed fix.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 48b4e5b3614f.

@greptile-apps

greptile-apps Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR changes the install command from curl ... | bash to curl ... | bash -s -- and adds a note claiming this prevents stdin consumption by the installer's interactive prompts.

  • The fix is ineffective: bash -s is a no-op here (bash already reads from stdin when no script file is given), and -- only ends option parsing. Neither flag changes how child processes inherit file descriptors, so gum prompts will still consume the piped script stream. The added note on line 48 documents behavior that does not occur and will mislead users who encounter the real hang.

Confidence Score: 3/5

Not safe to merge — the documented fix does not solve the stated problem and introduces a misleading note.

The sole change is a docs fix for a real bug (#73814), but the proposed fix (bash -s --) is technically incorrect: it is a no-op for stdin inheritance by child processes. The install command itself still works (bash runs the script), but the explanatory note is factually wrong and will leave users believing the issue is resolved when it is not. Score capped at 3 due to the P1 logic finding.

docs/start/getting-started.md — both the command change and the new note need to be reconsidered.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: docs/start/getting-started.md
Line: 48-49

Comment:
**`-s --` does not prevent child-process stdin consumption**

`bash -s` tells bash to read commands from stdin, but this is already the default when no script file is passed — it is a no-op here. Crucially, child processes (like `gum`) inherit the parent's file descriptors unchanged, so they still read from the same pipe. The note on line 48 is therefore misleading: users who follow this command will still encounter the interactive-prompt hang described in the linked issue.

The correct caller-side fix is process substitution, which passes the script via a file descriptor rather than stdin, leaving stdin available for TTY prompts:

```bash
bash <(curl -fsSL https://openclaw.ai/install.sh)
```

Alternatively, the real fix belongs in `install.sh` itself — redirect `gum`'s stdin from `/dev/tty` (e.g. `gum choose < /dev/tty`) so the prompt is terminal-backed regardless of how the outer script is invoked.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "docs: add -s -- flags to curl|bash insta..." | Re-trigger Greptile

Comment on lines +48 to 49
The `-s --` flags prevent the installer from consuming stdin when piped via `curl | bash`.
Other install methods (Docker, Nix, npm): [Install](/install).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 -s -- does not prevent child-process stdin consumption

bash -s tells bash to read commands from stdin, but this is already the default when no script file is passed — it is a no-op here. Crucially, child processes (like gum) inherit the parent's file descriptors unchanged, so they still read from the same pipe. The note on line 48 is therefore misleading: users who follow this command will still encounter the interactive-prompt hang described in the linked issue.

The correct caller-side fix is process substitution, which passes the script via a file descriptor rather than stdin, leaving stdin available for TTY prompts:

bash <(curl -fsSL https://openclaw.ai/install.sh)

Alternatively, the real fix belongs in install.sh itself — redirect gum's stdin from /dev/tty (e.g. gum choose < /dev/tty) so the prompt is terminal-backed regardless of how the outer script is invoked.

Prompt To Fix With AI
This is a comment left during a code review.
Path: docs/start/getting-started.md
Line: 48-49

Comment:
**`-s --` does not prevent child-process stdin consumption**

`bash -s` tells bash to read commands from stdin, but this is already the default when no script file is passed — it is a no-op here. Crucially, child processes (like `gum`) inherit the parent's file descriptors unchanged, so they still read from the same pipe. The note on line 48 is therefore misleading: users who follow this command will still encounter the interactive-prompt hang described in the linked issue.

The correct caller-side fix is process substitution, which passes the script via a file descriptor rather than stdin, leaving stdin available for TTY prompts:

```bash
bash <(curl -fsSL https://openclaw.ai/install.sh)
```

Alternatively, the real fix belongs in `install.sh` itself — redirect `gum`'s stdin from `/dev/tty` (e.g. `gum choose < /dev/tty`) so the prompt is terminal-backed regardless of how the outer script is invoked.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Closing in favor of a revised approach. The -s -- approach is insufficient per code review feedback — process substitution (bash <(curl -fsSL https://openclaw.ai/install.sh)) is the correct caller-side fix.

@unn-Known1

Copy link
Copy Markdown
Author

Greptile Review Acknowledgment

Thank you for the P1/P2 feedback. This is noted for the next revision.

Status: Merge conflict must be resolved first. Will address these comments after rebase.


Automated acknowledgment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation size: XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Installer hangs and truncates function "warn_shell_path_missing_di" in install.sh presumably due to stdin consumption from "curl | bash"

2 participants