This StackOverflow thread details how, using set
and shopt
, you may use the built-in ‘yes’ to automate bash script interactions with ‘read’. However, there’s a catch to automation this way: Both, using built-in yes |
and process substitution < <(yes)
are going to fail to script you through a bash script for every other read
in this case:
$ cat test-script.sh shopt -s lastpipe; set +m; #set -x; continueYesNo() { local msg="$@"; echo "$msg"; read -er -n 1 -p "$this: INFO: Continue [y|N]?: " REPLY; if test "$REPLY" = "y"; then return 0; else return 1; fi; } continueYesNo "question1? "; echo "result: $?"; continueYesNo "question2? "; echo "result: $?"; continueYesNo "question3? "; echo "result: $?"; ### More concise but equally failing with 'yes': read -n 1 -p "[y|N]?:" REPLY; echo "reply: $REPLY"; read -n 1 -p "[y|N]?:" REPLY; echo "reply: $REPLY"; read -n 1 -p "[y|N]?:" REPLY; echo "reply: $REPLY"; # EOF $ yes | bash test-script.sh reply: y reply: reply: y question1? result: 1 question2? result: 0 question3? result: 1
Solution: to work around this bash automation catch with built-in read and yes use echo "yyy" | ./test-script.sh
if you’re going to answer 3 (three) read
‘s worth of questions.
$ echo "yyy" | bash test-script.sh reply: y reply: y reply: y question1? result: 1 question2? result: 1 question3? result: 1
Reason for this is read -n 1
is only going to consume 1 char for an answer but yes
is by default providing ‘y’ and a newline (\n
). So every other read
is consuming the \n
and the script thus failing to continue.
See also help read
:
-n nchars return after reading NCHARS characters rather than waiting for a newline, but honour a delimiter if fewer than NCHARS characters
are read before the delimiter