Skip to content

fix: redirect stdin to /dev/tty for interactive read commands in pipe…#36

Open
iam-joey wants to merge 3 commits intomainfrom
fix/stdin-tty-interactive-read
Open

fix: redirect stdin to /dev/tty for interactive read commands in pipe…#36
iam-joey wants to merge 3 commits intomainfrom
fix/stdin-tty-interactive-read

Conversation

@iam-joey
Copy link
Copy Markdown
Contributor

@iam-joey iam-joey commented Apr 8, 2026

…d execution

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 8, 2026

Summary by CodeRabbit

  • Bug Fixes
    • Fixed the setup utility so interactive prompts reliably accept input even when run in non-interactive contexts (e.g., pipelines).
    • Ensured the setup process exits cleanly after completion to avoid lingering background processes.

Walkthrough

All interactive read prompts in setup_payram.sh were changed to read explicitly from the controlling terminal (</dev/tty), and the script now exits with exit 0 immediately after main "$@". (≤50 words)

Changes

Cohort / File(s) Summary
Interactive input & termination
setup_payram.sh
Appended </dev/tty to all read prompts (disk-space checks, DB selection/config, SSL flows, AES key generation, upgrade/update/menus, final deploy prompt) to force input from the controlling terminal; added explicit exit 0 after main "$@".

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • PayRam/payram-scripts#33 — Modifies interactive input handling in setup_payram.sh (related changes to read usage across database, SSL, AES, and menu prompts).

Suggested reviewers

  • sam6230i
  • gulshanweb3

Poem

🐇 I nudged the tty with a curious paw,

Prompts woke up and answered my awe,
Pipelines hum and scripts now reply,
A terminal wink beneath moonlit sky,
Hop, deploy — the rabbit's done, bye-bye!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: redirecting stdin to /dev/tty for interactive read commands in piped execution, which matches the core objective of the pull request.
Description check ✅ Passed The description, though truncated ('…d execution'), is related to the changeset as it refers to piped execution context, which aligns with the title and commit message about stdin redirection for interactive prompts.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/stdin-tty-interactive-read

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@setup_payram.sh`:
- Around line 3716-3718: The current stdin redirection line ([[ -t 0 ]] || exec
< /dev/tty) can abort the script in non-TTY environments; change it to first
check that /dev/tty exists and is readable before attempting the exec so
non-interactive CI/cron/systemd runs won't fail. Replace the unconditional exec
branch with a guarded test (e.g., ensure /dev/tty exists and is a character
device or is readable) and only run exec < /dev/tty when that check and the
existing [[ -t 0 ]] test indicate a real tty; update the line containing [[ -t 0
]] || exec < /dev/tty accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 08b139ee-3695-4157-9e8c-ae3c1f8f6cd5

📥 Commits

Reviewing files that changed from the base of the PR and between c475627 and 863291d.

📒 Files selected for processing (1)
  • setup_payram.sh

setup_payram.sh Outdated
Comment on lines +3716 to +3718
# When the script is piped (curl | bash), stdin is the pipe — not the terminal.
# Redirect stdin to /dev/tty so all interactive read commands work correctly.
[[ -t 0 ]] || exec < /dev/tty
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.

⚠️ Potential issue | 🟠 Major

Guard /dev/tty redirection to avoid hard failure in non-TTY environments.

Line 3718 can terminate the script under set -e when /dev/tty is unavailable (common in CI/cron/systemd). That breaks otherwise non-interactive paths.

Suggested fix
-  [[ -t 0 ]] || exec < /dev/tty
+  if [[ ! -t 0 ]]; then
+    # When piped, restore interactive stdin only if a controlling TTY exists.
+    if [[ -r /dev/tty ]]; then
+      exec < /dev/tty
+    fi
+  fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# When the script is piped (curl | bash), stdin is the pipe — not the terminal.
# Redirect stdin to /dev/tty so all interactive read commands work correctly.
[[ -t 0 ]] || exec < /dev/tty
# When the script is piped (curl | bash), stdin is the pipe — not the terminal.
# Redirect stdin to /dev/tty so all interactive read commands work correctly.
if [[ ! -t 0 ]]; then
# When piped, restore interactive stdin only if a controlling TTY exists.
if [[ -r /dev/tty ]]; then
exec < /dev/tty
fi
fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup_payram.sh` around lines 3716 - 3718, The current stdin redirection line
([[ -t 0 ]] || exec < /dev/tty) can abort the script in non-TTY environments;
change it to first check that /dev/tty exists and is readable before attempting
the exec so non-interactive CI/cron/systemd runs won't fail. Replace the
unconditional exec branch with a guarded test (e.g., ensure /dev/tty exists and
is a character device or is readable) and only run exec < /dev/tty when that
check and the existing [[ -t 0 ]] test indicate a real tty; update the line
containing [[ -t 0 ]] || exec < /dev/tty accordingly.

@coderabbitai coderabbitai bot requested review from gulshanweb3 and sam6230i April 8, 2026 06:16
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
setup_payram.sh (1)

775-3898: ⚠️ Potential issue | 🟠 Major

Guard /dev/tty reads to avoid hard exits when no controlling TTY exists.

All the new read ... </dev/tty calls will abort the script under set -e if /dev/tty is unavailable (common in CI/cron/systemd or detached sudo sessions). Please centralize this with a guarded helper and fail with a clear message instead of redirection errors.

Suggested fix pattern
+tty_read() {
+  if [[ ! -r /dev/tty ]]; then
+    log "ERROR" "Interactive input required, but no controlling TTY is available."
+    return 1
+  fi
+  read "$@" </dev/tty
+}
...
-    read -e -p "Select option (1-2): " choice </dev/tty
+    tty_read -e -p "Select option (1-2): " choice
#!/bin/bash
# Verify all direct /dev/tty reads and whether a guard/helper exists.
rg -n 'read\b.*</dev/tty' setup_payram.sh
rg -n 'tty_read\(|\[\[ *-r */dev/tty *\]\]|exec *< */dev/tty' setup_payram.sh
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup_payram.sh` around lines 775 - 3898, Many interactive reads use direct
redirection "read ... </dev/tty" which will cause the script to abort under set
-e when /dev/tty is unavailable (CI/cron/daemon). Add a centralized guarded
helper (e.g. check_tty_or_fail and tty_read wrapper) that verifies /dev/tty is
readable and either performs the read or prints a clear error and exits
non-zero; then replace all raw uses of "read ... </dev/tty" across interactive
entry points (e.g. configure_database, configure_external_database,
configure_internal_database, configure_ssl, configure_ssl_letsencrypt,
configure_ssl_custom, configure_ssl_update*, generate_aes_key,
show_interactive_menu, show_network_selection, reset_payram_environment,
display_firewall_notice, display_access_urls, and any other functions) to call
the wrapper; ensure non-interactive helper functions keep returning graceful
error codes (not causing an unexpected hard exit) so scripts invoked in non-TTY
contexts can fail with a clear message.
🧹 Nitpick comments (1)
setup_payram.sh (1)

3923-3924: Propagate main exit status instead of unconditional success.

With set -euo pipefail at script level (line 2) and no intervening set +e at script scope, the unconditional exit 0 masks the actual exit status of main, which can return non-zero for error cases (e.g., unknown options at line 3760). This breaks proper error signaling to calling processes. Use exit $? to propagate the status.

Suggested fix
 main "$@"
-exit 0
+exit $?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@setup_payram.sh` around lines 3923 - 3924, The script currently calls main
"$@" and then unconditionally exits with exit 0 which masks main's return code;
change the script so that after invoking main "$@" it exits with main's actual
status (propagate "$?" or use an immediate exit with the command's status) so
failures from main (e.g., unknown option handling in main) are signaled to
callers; update the lines invoking main and exit to capture and re-exit with
main's exit code while keeping existing shell options like set -euo pipefail
intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@setup_payram.sh`:
- Around line 775-3898: Many interactive reads use direct redirection "read ...
</dev/tty" which will cause the script to abort under set -e when /dev/tty is
unavailable (CI/cron/daemon). Add a centralized guarded helper (e.g.
check_tty_or_fail and tty_read wrapper) that verifies /dev/tty is readable and
either performs the read or prints a clear error and exits non-zero; then
replace all raw uses of "read ... </dev/tty" across interactive entry points
(e.g. configure_database, configure_external_database,
configure_internal_database, configure_ssl, configure_ssl_letsencrypt,
configure_ssl_custom, configure_ssl_update*, generate_aes_key,
show_interactive_menu, show_network_selection, reset_payram_environment,
display_firewall_notice, display_access_urls, and any other functions) to call
the wrapper; ensure non-interactive helper functions keep returning graceful
error codes (not causing an unexpected hard exit) so scripts invoked in non-TTY
contexts can fail with a clear message.

---

Nitpick comments:
In `@setup_payram.sh`:
- Around line 3923-3924: The script currently calls main "$@" and then
unconditionally exits with exit 0 which masks main's return code; change the
script so that after invoking main "$@" it exits with main's actual status
(propagate "$?" or use an immediate exit with the command's status) so failures
from main (e.g., unknown option handling in main) are signaled to callers;
update the lines invoking main and exit to capture and re-exit with main's exit
code while keeping existing shell options like set -euo pipefail intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9fdc900f-1d19-4beb-8209-67b77b9bb3b8

📥 Commits

Reviewing files that changed from the base of the PR and between 84c06ee and 8d6fe79.

📒 Files selected for processing (1)
  • setup_payram.sh

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant