From c10638ae9209f7f15c534f065b19350179abe543 Mon Sep 17 00:00:00 2001 From: BeLazy167 Date: Thu, 20 Aug 2026 16:18:26 -0500 Subject: [PATCH] Probe /dev/tty by opening it, not by testing permission bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [ -r /dev/tty ] passes in environments where the device exists but cannot be opened (macOS reports 'Device not configured' only on open). The installer then tried to prompt anyway: three open errors and a retry loop instead of the clean 'no terminal — set QBRAID_API_KEY and re-run' message. Verified both directions: under a real pty (script(1)) the probe yields /dev/tty; with the unopenable device it yields empty and the installer dies with the instruction. --- install.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/install.sh b/install.sh index 2b8ec20..c20dec9 100755 --- a/install.sh +++ b/install.sh @@ -75,8 +75,11 @@ die() { printf '\n%serror:%s %s\n' "$red" "$rst" "$*" >&2; exit 1; } # When this script is piped from curl, stdin is the script itself — prompts # must read the keyboard directly. If there is no terminal at all (CI), the # install has to be driven entirely by environment variables. +# `[ -r /dev/tty ]` passes even where the device cannot actually be opened +# (some CI harnesses report "Device not configured" only on open), so probe by +# really opening it in both directions. TTY="" -if [ -r /dev/tty ] && [ -w /dev/tty ]; then TTY=/dev/tty; fi +if (exec 3/dev/null && (exec 3>/dev/tty) 2>/dev/null; then TTY=/dev/tty; fi prompt() { # prompt -> echoes the answer local q="$1" reply=""