Question about select menus in bash

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP








up vote
1
down vote

favorite












Before you tell me "there are tons of guides on this already" know that I actually have a select menu made and it is working.



However there is one thing that is driving me nuts. The way I have this menu coded currently this is what occurs:



1) User picks an option
2) Menu reloads
3) Option has an asterick next to it to show it is selected.



Problem:



The user has to select each option one at a time after the menu reloads after each selection. As you can imagine this is slow and make the terminal window messy.



What I want:



The user should be able to type 1-4 or 1,4,7 to select multiple options.



What I don't want:



A Whiptail or Dialog. I actually did make one as well and it is flawless. However I would prefer not to use it if I can help it or use it as a fallback. I think it would be more user friendly (not to mention easier on the eyes) to not use one.



Code:



# #
### CSGO Plugin selection ###
# #

options=(
"SurfTimer - 2.02 - Core of this server."
"AutoFileLoader - Caches all material, model, and sound files for players to download."
"Chat-Procesor - Chat Processing Plugin"
"Dynamic - PreReq for many plugins to work properly."
"FixAngles - Fixes 'wrong angle on material' error that gets spammed in console when using store items"
"Mapchooser_Extended - Map Vote System. See maplist.cfg/mapcycle.cfg.")
....


menu()
echo "Avaliable options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done
[[ "$msg" ]] && echo "$msg"; :


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" != *[![:digit:]]* ]] &&
(( num > 0 && num <= $#options[@] )) ||
msg="Invalid option: $num"; continue;
((num--)); msg="$options[num] was $choices[num]:+unchecked"
[[ "$choices[num]" ]] && choices[num]="" || choices[num]="+"
done

printf "You selected"; msg=" nothing"
for i in $!options[@]; do
[[ "$choices[i]" ]] && printf " %s" "$options[i]"; msg="";
done









share|improve this question























  • I wrote a little limerick, to show you something printed thick, there is a char, looks like a star, the word you want is asterisk.
    – dessert
    Mar 11 at 21:31










  • @dessert great. Are you gonna add anything meaningful to the discussion or are you just gonna correct people's grammar all day.
    – Sandman007
    Mar 11 at 21:54










  • I can do both. proud
    – dessert
    Mar 11 at 23:56














up vote
1
down vote

favorite












Before you tell me "there are tons of guides on this already" know that I actually have a select menu made and it is working.



However there is one thing that is driving me nuts. The way I have this menu coded currently this is what occurs:



1) User picks an option
2) Menu reloads
3) Option has an asterick next to it to show it is selected.



Problem:



The user has to select each option one at a time after the menu reloads after each selection. As you can imagine this is slow and make the terminal window messy.



What I want:



The user should be able to type 1-4 or 1,4,7 to select multiple options.



What I don't want:



A Whiptail or Dialog. I actually did make one as well and it is flawless. However I would prefer not to use it if I can help it or use it as a fallback. I think it would be more user friendly (not to mention easier on the eyes) to not use one.



Code:



# #
### CSGO Plugin selection ###
# #

options=(
"SurfTimer - 2.02 - Core of this server."
"AutoFileLoader - Caches all material, model, and sound files for players to download."
"Chat-Procesor - Chat Processing Plugin"
"Dynamic - PreReq for many plugins to work properly."
"FixAngles - Fixes 'wrong angle on material' error that gets spammed in console when using store items"
"Mapchooser_Extended - Map Vote System. See maplist.cfg/mapcycle.cfg.")
....


menu()
echo "Avaliable options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done
[[ "$msg" ]] && echo "$msg"; :


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" != *[![:digit:]]* ]] &&
(( num > 0 && num <= $#options[@] )) ||
msg="Invalid option: $num"; continue;
((num--)); msg="$options[num] was $choices[num]:+unchecked"
[[ "$choices[num]" ]] && choices[num]="" || choices[num]="+"
done

printf "You selected"; msg=" nothing"
for i in $!options[@]; do
[[ "$choices[i]" ]] && printf " %s" "$options[i]"; msg="";
done









share|improve this question























  • I wrote a little limerick, to show you something printed thick, there is a char, looks like a star, the word you want is asterisk.
    – dessert
    Mar 11 at 21:31










  • @dessert great. Are you gonna add anything meaningful to the discussion or are you just gonna correct people's grammar all day.
    – Sandman007
    Mar 11 at 21:54










  • I can do both. proud
    – dessert
    Mar 11 at 23:56












up vote
1
down vote

favorite









up vote
1
down vote

favorite











Before you tell me "there are tons of guides on this already" know that I actually have a select menu made and it is working.



However there is one thing that is driving me nuts. The way I have this menu coded currently this is what occurs:



1) User picks an option
2) Menu reloads
3) Option has an asterick next to it to show it is selected.



Problem:



The user has to select each option one at a time after the menu reloads after each selection. As you can imagine this is slow and make the terminal window messy.



What I want:



The user should be able to type 1-4 or 1,4,7 to select multiple options.



What I don't want:



A Whiptail or Dialog. I actually did make one as well and it is flawless. However I would prefer not to use it if I can help it or use it as a fallback. I think it would be more user friendly (not to mention easier on the eyes) to not use one.



Code:



# #
### CSGO Plugin selection ###
# #

options=(
"SurfTimer - 2.02 - Core of this server."
"AutoFileLoader - Caches all material, model, and sound files for players to download."
"Chat-Procesor - Chat Processing Plugin"
"Dynamic - PreReq for many plugins to work properly."
"FixAngles - Fixes 'wrong angle on material' error that gets spammed in console when using store items"
"Mapchooser_Extended - Map Vote System. See maplist.cfg/mapcycle.cfg.")
....


menu()
echo "Avaliable options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done
[[ "$msg" ]] && echo "$msg"; :


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" != *[![:digit:]]* ]] &&
(( num > 0 && num <= $#options[@] )) ||
msg="Invalid option: $num"; continue;
((num--)); msg="$options[num] was $choices[num]:+unchecked"
[[ "$choices[num]" ]] && choices[num]="" || choices[num]="+"
done

printf "You selected"; msg=" nothing"
for i in $!options[@]; do
[[ "$choices[i]" ]] && printf " %s" "$options[i]"; msg="";
done









share|improve this question















Before you tell me "there are tons of guides on this already" know that I actually have a select menu made and it is working.



However there is one thing that is driving me nuts. The way I have this menu coded currently this is what occurs:



1) User picks an option
2) Menu reloads
3) Option has an asterick next to it to show it is selected.



Problem:



The user has to select each option one at a time after the menu reloads after each selection. As you can imagine this is slow and make the terminal window messy.



What I want:



The user should be able to type 1-4 or 1,4,7 to select multiple options.



What I don't want:



A Whiptail or Dialog. I actually did make one as well and it is flawless. However I would prefer not to use it if I can help it or use it as a fallback. I think it would be more user friendly (not to mention easier on the eyes) to not use one.



Code:



# #
### CSGO Plugin selection ###
# #

options=(
"SurfTimer - 2.02 - Core of this server."
"AutoFileLoader - Caches all material, model, and sound files for players to download."
"Chat-Procesor - Chat Processing Plugin"
"Dynamic - PreReq for many plugins to work properly."
"FixAngles - Fixes 'wrong angle on material' error that gets spammed in console when using store items"
"Mapchooser_Extended - Map Vote System. See maplist.cfg/mapcycle.cfg.")
....


menu()
echo "Avaliable options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done
[[ "$msg" ]] && echo "$msg"; :


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" != *[![:digit:]]* ]] &&
(( num > 0 && num <= $#options[@] )) ||
msg="Invalid option: $num"; continue;
((num--)); msg="$options[num] was $choices[num]:+unchecked"
[[ "$choices[num]" ]] && choices[num]="" || choices[num]="+"
done

printf "You selected"; msg=" nothing"
for i in $!options[@]; do
[[ "$choices[i]" ]] && printf " %s" "$options[i]"; msg="";
done






bash scripts menu






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Mar 11 at 21:57









dessert

19.9k55795




19.9k55795










asked Mar 11 at 20:35









Sandman007

3027




3027











  • I wrote a little limerick, to show you something printed thick, there is a char, looks like a star, the word you want is asterisk.
    – dessert
    Mar 11 at 21:31










  • @dessert great. Are you gonna add anything meaningful to the discussion or are you just gonna correct people's grammar all day.
    – Sandman007
    Mar 11 at 21:54










  • I can do both. proud
    – dessert
    Mar 11 at 23:56
















  • I wrote a little limerick, to show you something printed thick, there is a char, looks like a star, the word you want is asterisk.
    – dessert
    Mar 11 at 21:31










  • @dessert great. Are you gonna add anything meaningful to the discussion or are you just gonna correct people's grammar all day.
    – Sandman007
    Mar 11 at 21:54










  • I can do both. proud
    – dessert
    Mar 11 at 23:56















I wrote a little limerick, to show you something printed thick, there is a char, looks like a star, the word you want is asterisk.
– dessert
Mar 11 at 21:31




I wrote a little limerick, to show you something printed thick, there is a char, looks like a star, the word you want is asterisk.
– dessert
Mar 11 at 21:31












@dessert great. Are you gonna add anything meaningful to the discussion or are you just gonna correct people's grammar all day.
– Sandman007
Mar 11 at 21:54




@dessert great. Are you gonna add anything meaningful to the discussion or are you just gonna correct people's grammar all day.
– Sandman007
Mar 11 at 21:54












I can do both. proud
– dessert
Mar 11 at 23:56




I can do both. proud
– dessert
Mar 11 at 23:56










1 Answer
1






active

oldest

votes

















up vote
2
down vote



accepted










I'd do it as follows:



menu() 
clear
echo "Available options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" =~ "-" ]] && num=$(seq $(sed -E 's/(d*)-(d*)/1 2/' <<<"$num"))
for i in $num; do
((i--))
[[ "$choices[i]" ]] && choices[i]="" || choices[i]="*"
done
done


This tests if $num contains a hyphen and builds the range if necessary, then simply loops over the content of $num so that users can give multiple options at once with e.g. 1 2 4 or 1-4 (but not a combination of those!). It also clears the terminal every time before the menu is printed.






share|improve this answer






















  • Flawless! Thank You! Although I am having trouble with the range. I am pretty new to bash so I could just be putting it in the wrong spot. I assume it should go right after the for loop but inside the while loop?
    – Sandman007
    Mar 11 at 23:20










  • Hmm still not working. I did put it right before the for loop. But if you can't figure it out don't worry about it. You've already been a great help!
    – Sandman007
    Mar 11 at 23:41











  • @Sandman007 Really? I edited it in, it works perfectly for me with GNU bash 4.3.48(1)…
    – dessert
    Mar 11 at 23:55










Your Answer







StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "89"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1013965%2fquestion-about-select-menus-in-bash%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
2
down vote



accepted










I'd do it as follows:



menu() 
clear
echo "Available options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" =~ "-" ]] && num=$(seq $(sed -E 's/(d*)-(d*)/1 2/' <<<"$num"))
for i in $num; do
((i--))
[[ "$choices[i]" ]] && choices[i]="" || choices[i]="*"
done
done


This tests if $num contains a hyphen and builds the range if necessary, then simply loops over the content of $num so that users can give multiple options at once with e.g. 1 2 4 or 1-4 (but not a combination of those!). It also clears the terminal every time before the menu is printed.






share|improve this answer






















  • Flawless! Thank You! Although I am having trouble with the range. I am pretty new to bash so I could just be putting it in the wrong spot. I assume it should go right after the for loop but inside the while loop?
    – Sandman007
    Mar 11 at 23:20










  • Hmm still not working. I did put it right before the for loop. But if you can't figure it out don't worry about it. You've already been a great help!
    – Sandman007
    Mar 11 at 23:41











  • @Sandman007 Really? I edited it in, it works perfectly for me with GNU bash 4.3.48(1)…
    – dessert
    Mar 11 at 23:55














up vote
2
down vote



accepted










I'd do it as follows:



menu() 
clear
echo "Available options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" =~ "-" ]] && num=$(seq $(sed -E 's/(d*)-(d*)/1 2/' <<<"$num"))
for i in $num; do
((i--))
[[ "$choices[i]" ]] && choices[i]="" || choices[i]="*"
done
done


This tests if $num contains a hyphen and builds the range if necessary, then simply loops over the content of $num so that users can give multiple options at once with e.g. 1 2 4 or 1-4 (but not a combination of those!). It also clears the terminal every time before the menu is printed.






share|improve this answer






















  • Flawless! Thank You! Although I am having trouble with the range. I am pretty new to bash so I could just be putting it in the wrong spot. I assume it should go right after the for loop but inside the while loop?
    – Sandman007
    Mar 11 at 23:20










  • Hmm still not working. I did put it right before the for loop. But if you can't figure it out don't worry about it. You've already been a great help!
    – Sandman007
    Mar 11 at 23:41











  • @Sandman007 Really? I edited it in, it works perfectly for me with GNU bash 4.3.48(1)…
    – dessert
    Mar 11 at 23:55












up vote
2
down vote



accepted







up vote
2
down vote



accepted






I'd do it as follows:



menu() 
clear
echo "Available options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" =~ "-" ]] && num=$(seq $(sed -E 's/(d*)-(d*)/1 2/' <<<"$num"))
for i in $num; do
((i--))
[[ "$choices[i]" ]] && choices[i]="" || choices[i]="*"
done
done


This tests if $num contains a hyphen and builds the range if necessary, then simply loops over the content of $num so that users can give multiple options at once with e.g. 1 2 4 or 1-4 (but not a combination of those!). It also clears the terminal every time before the menu is printed.






share|improve this answer














I'd do it as follows:



menu() 
clear
echo "Available options:"
for i in $!options[@]; do
printf "%3d%s) %sn" $((i+1)) "$choices[i]:- " "$options[i]"
done


prompt="Check an option (again to uncheck, ENTER when done): "
while menu && read -rp "$prompt" num && [[ "$num" ]]; do
[[ "$num" =~ "-" ]] && num=$(seq $(sed -E 's/(d*)-(d*)/1 2/' <<<"$num"))
for i in $num; do
((i--))
[[ "$choices[i]" ]] && choices[i]="" || choices[i]="*"
done
done


This tests if $num contains a hyphen and builds the range if necessary, then simply loops over the content of $num so that users can give multiple options at once with e.g. 1 2 4 or 1-4 (but not a combination of those!). It also clears the terminal every time before the menu is printed.







share|improve this answer














share|improve this answer



share|improve this answer








edited Mar 11 at 23:54

























answered Mar 11 at 22:48









dessert

19.9k55795




19.9k55795











  • Flawless! Thank You! Although I am having trouble with the range. I am pretty new to bash so I could just be putting it in the wrong spot. I assume it should go right after the for loop but inside the while loop?
    – Sandman007
    Mar 11 at 23:20










  • Hmm still not working. I did put it right before the for loop. But if you can't figure it out don't worry about it. You've already been a great help!
    – Sandman007
    Mar 11 at 23:41











  • @Sandman007 Really? I edited it in, it works perfectly for me with GNU bash 4.3.48(1)…
    – dessert
    Mar 11 at 23:55
















  • Flawless! Thank You! Although I am having trouble with the range. I am pretty new to bash so I could just be putting it in the wrong spot. I assume it should go right after the for loop but inside the while loop?
    – Sandman007
    Mar 11 at 23:20










  • Hmm still not working. I did put it right before the for loop. But if you can't figure it out don't worry about it. You've already been a great help!
    – Sandman007
    Mar 11 at 23:41











  • @Sandman007 Really? I edited it in, it works perfectly for me with GNU bash 4.3.48(1)…
    – dessert
    Mar 11 at 23:55















Flawless! Thank You! Although I am having trouble with the range. I am pretty new to bash so I could just be putting it in the wrong spot. I assume it should go right after the for loop but inside the while loop?
– Sandman007
Mar 11 at 23:20




Flawless! Thank You! Although I am having trouble with the range. I am pretty new to bash so I could just be putting it in the wrong spot. I assume it should go right after the for loop but inside the while loop?
– Sandman007
Mar 11 at 23:20












Hmm still not working. I did put it right before the for loop. But if you can't figure it out don't worry about it. You've already been a great help!
– Sandman007
Mar 11 at 23:41





Hmm still not working. I did put it right before the for loop. But if you can't figure it out don't worry about it. You've already been a great help!
– Sandman007
Mar 11 at 23:41













@Sandman007 Really? I edited it in, it works perfectly for me with GNU bash 4.3.48(1)…
– dessert
Mar 11 at 23:55




@Sandman007 Really? I edited it in, it works perfectly for me with GNU bash 4.3.48(1)…
– dessert
Mar 11 at 23:55

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f1013965%2fquestion-about-select-menus-in-bash%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

How do so many people here on Academia.SE, and in general, afford lavish higher education programs?

Trouble downloading packages list due to a “Hash sum mismatch” error

How do I move numbers in filenames, in a batch renaming operation?