Question about select menus in bash

Clash 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
bash scripts menu
add a comment |Â
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
bash scripts menu
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
add a comment |Â
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
bash scripts menu
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
bash scripts menu
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
add a comment |Â
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
add a comment |Â
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.
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 withGNU bash 4.3.48(1)â¦
â dessert
Mar 11 at 23:55
add a comment |Â
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.
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 withGNU bash 4.3.48(1)â¦
â dessert
Mar 11 at 23:55
add a comment |Â
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.
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 withGNU bash 4.3.48(1)â¦
â dessert
Mar 11 at 23:55
add a comment |Â
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.
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.
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 withGNU bash 4.3.48(1)â¦
â dessert
Mar 11 at 23:55
add a comment |Â
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 withGNU 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
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e)
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom))
StackExchange.using('gps', function() StackExchange.gps.track('embedded_signup_form.view', location: 'question_page' ); );
$window.unbind('scroll', onScroll);
;
$window.on('scroll', onScroll);
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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