scripts: Add functions to detect an interactive terminal

With more interactive features appearing in the scripts, we need to
avoid hanging buildbots waiting for user input. This changes adds
utility functions to test whether and ensure that the execution is
interactive, and adds an assertion to the 'choose' function.

is_interactive: Check that both stdin and stderr are terminals.
assert_interactive: Die with an error if not interactive

Also tweaking 'choose' so that its menu is printed to stderr,
for consistency with read -p and select.

BUG=None
TEST=Modified setup_board to log the value of is_interactive, and
  then (unconditionally) attempt to display a menu.
  Running setup_board in a terminal showed interactive and the menu.
  Manually run cbuildbot x86-generic-pfq showed non-interactive and
  the assertion failure.

Change-Id: I768a37b8b85ce036edac7c9bb0fd1e0a2b92ecd5
Reviewed-on: https://gerrit.chromium.org/gerrit/16817
Commit-Ready: Chris Wolfe <cwolfe@chromium.org>
Reviewed-by: Chris Wolfe <cwolfe@chromium.org>
Tested-by: Chris Wolfe <cwolfe@chromium.org>
This commit is contained in:
Chris Wolfe 2012-02-27 13:00:51 -05:00 committed by Gerrit
parent ae6b96f3ab
commit 21a27b75e9

View File

@ -776,6 +776,20 @@ function enable_strict_sudo {
}
}
# Checks that stdin and stderr are both terminals.
# If so, we assume that there is a live user we can interact with.
# This check can be overridden by setting the CROS_NO_PROMPT environment
# variable to a non-empty value.
function is_interactive() {
[ -z "${CROS_NO_PROMPT}" -a -t 0 -a -t 2 ]
}
function assert_interactive() {
if ! is_interactive; then
die "Script ${0##*/} tried to get user input on a non-interactive terminal."
fi
}
# Selection menu with a default option: this is similar to bash's select
# built-in, only that in case of an empty selection it'll return the default
# choice. Like select, it uses PS3 as the prompt.
@ -814,10 +828,12 @@ function choose() {
# Select a return value
unset REPLY
if [ $# -gt 0 ]; then
assert_interactive
# Actual options provided, present a menu and prompt for a choice.
local choose_opt
for choose_opt in "$@"; do
echo "$choose_i) $choose_opt"
echo "$choose_i) $choose_opt" >&2
choose_i=choose_i+1
done
read -p "$PS3"