fix(install): read prompts from /dev/tty so curl | bash works#525
Merged
Conversation
When piped via 'curl ... | sudo bash', stdin is the script text, not the terminal. Interactive read calls returned EOF immediately, and under 'set -e' the script exited silently after creating the install dir. Fix: redirect all read calls to /dev/tty. Add a guard that fails with a clear message when no terminal is available.
Script exited silently after collecting config. Root causes: - set -e killed the script on any non-zero return with no message - mkdir/cd failures were not reported Changes: - Drop 'set -e' (keep 'set -uo pipefail'), add EXIT trap that prints a visible message on non-zero exit - Explicit error handling around mkdir and cd with actionable hints
Two root causes for the script exiting silently after prompts: 1. gen_password piped /dev/urandom into 'head -c', which closes the pipe early and raises SIGPIPE, killing the pipeline (and script). Fix: read a fixed 4096-byte chunk via process substitution, then cut. 2. Under 'curl ... | bash' the script body lives on stdin. After the last /dev/tty read, bash had no more script to read and exited. Fix: when stdin is not a TTY, re-download to a temp file and re-exec with 'bash $tmp < /dev/tty' (guarded by EXPENSAVE_REEXEC).
Previous re-exec fetched install.sh from main, so testing a branch would
run the OLD main version — masking the fix and still dying in the old
gen_password. Instead, copy this very script from stdin to a temp file
('cat > $tmp') and re-exec it with /dev/tty as stdin. No re-download,
no version drift.
- gen_password: no pipes/process-substitution, transform in-memory - re-exec: drop $@ passthrough, add debug markers - add [debug] marker between collect_config and do_install to pinpoint where it stops
The re-exec copied stdin to a temp file, but bash had ALREADY consumed the first ~19 lines (including COMPOSE_URL and DEFAULT_INSTALL_DIR definitions) before 'cat > tmp' ran. The re-exec'd copy was missing those vars — hence empty install dir and 'curl: (3) bad URL'. Fix: - Remove re-exec entirely. Interactive reads already use /dev/tty, which works fine under 'curl | bash'. - Restore 'set -e' so failed curl/sed/docker commands stop the script instead of printing a fake success checkmark. - Keep a trap for a clear failure message.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Running the installer via
curl -fsSL .../install.sh | sudo bashexited silently right afterCreating directory.Cause: when piped, stdin is the script text, not the terminal. Interactive
readcalls hit EOF immediately, and underset -euo pipefailthe non-zero return killed the script without any error.Fix
readcalls (ask,ask_secret,confirm) to< /dev/ttymain()that fails with a clear message if no terminal is availableResult
curl -fsSL .../install.sh | sudo bashnow prompts correctly and completes installation.