Reputation: 22620
For some reason this function always gets "n" as the input when I hit return, even though I would expect it to get an empty string or maybe a newline character. I would expect it to get just about anything EXCEPT "n"
function readtest() {-
local YorN # this ensures there is no left-over value in YorN
#echo -ne "Go ahead? [Y/n]"; read -q YorN # this version the same result as the next line
read -q "YorN?Go ahead? [Y/n]"
[[ "$YorN" = "\n" ]] && echo "Matched Newline" # I don't really expect this to return true: it's just here to test
[[ "$YorN" != "n" ]] && echo "Do the thing!" # I expect this test to return true... this is the weird thing, and central to my question
echo "## $YorN ##" # I always get "## n ##"
}
Why is the value of YorN
"n"???
Upvotes: 0
Views: 686
Reputation: 18339
This is the expected behavior when using the option -q
. Here is the relevant part of the ZSH manual:
read [ -rszpqAclneE ] [ -t [ num ] ] [ -k [ num ] ] [ -d delim ] [ -u n ] [ name[?prompt] ] [ name ... ]
[...]
-q
Read only one character from the terminal and set name to ‘
y
’ if this character was ‘y
’ or ‘Y
’ and to ‘n
’ otherwise. With this flag set the return status is zero only if the character was ‘y
’ or ‘Y
’. This option may be used with a timeout (see-t
); if the read times out, or encounters end of file, status 2 is returned. Input is read from the terminal unless one of-u
or-p
is present. This option may also be used within zle widgets.
If you want to have the opposite behavior, i.e. only assume a negative answer if you entered either ‘n’ or ‘N’ and a positive answer otherwise, you can use the option -k 1
:
function readtest {
local YorN
read -q "YorN?Go ahead? [Y/n]"
if [[ ${(U)YorN} == "N" ]] ; then
echo "Don't do the thing!"
else
echo "Go ahead!"
fi
}
Another option would be to invert the question:
read -q "YorN? Stop here? [y/N]"
Upvotes: 3