Walter A February 2016

Why does my menu with select fail the first time?

I tried to answer another SO question with a simple menu using the builtin select statement. The code displays names from /etc/passwd, and let you select a name by giving a number:

PS3="Enter a number: "
select name in $(cut -d: -f1 /etc/passwd) ; do
   if [ -n "${name}" ]; then
      break
   fi
   echo "Sorry, please enter a number as shown."
done
echo "Entry from passwd is: ${name}"

The works fine except for the very first time. When you give a correct answer the first time it will ask you to try again.
I tried to get a more detailed explanation of the first time, but I couldn't get a reproducable cook-book. When you copy-paste this code on your server, and give a correct answer you will probably have the same problem. When you repeat the command (from history or a new paste), the code shows now problem. I tried to get the problem again by logging out and logging in (sometimes it works) or rebooting.
I tried different ways to reproduce the problem in other situations (using different variable names, unsetting variables, using a slow list of values with select name in $(echo One; sleep 1; echo Two; sleep 2; echo Three; sleep 1); and opening a new shell.

I searched for other examples with select, but I can't find clues in other posts like http://stackoverflow.com/a/16750755/3220113 and http://askubuntu.com/a/1716.

I tried to fix my code with a sync and that seems to be a work-around:

PS3="Enter a number: "
select name in $(cut -d: -f1 /etc/passwd) ; do
   # is sync needed here?
   sync
   if [ -n "${name}" ]; then
      break
   fi
   echo "Sorry, please enter a number as shown."
done
echo "Entry from passwd is: ${name}"

I couldn't reproduce the error when I include the sync c

Answers


Barmar February 2016

This problem only occurs when you type the commands interactively, not in a script. The reason is that the line you type after the select line is being used as the response to the prompt. Since if isn't in the menu, it reports an error. Then it doesn't execute the if command, because it was read as the response to the prompt.

It's not a problem in a script because the commands in the script are not used as standard input.

Post Status

Asked in February 2016
Viewed 1,283 times
Voted 10
Answered 1 times

Search




Leave an answer