fill variable from bash menu - bash

Here is a pretty straight forward menu:
VAR=""
PS3='Make a selection: '
options=("opt 1" "opt 2" "opt 3" "Quit")
select opt in "${options[#]}"
do
case $opt in
"opt 1")
echo "opt 1 selected"
;;
"opt 2")
echo "opt 2 selected"
;;
"opt 3")
echo "opt 3 selected"
;;
"Quit")
break
;;
*) echo "invalid option $REPLY";;
esac
done
I would like for each option to add the following:
for instance if "opt 1" is selected:
[[ $(VAR) ]] && VAR="${VAR}\|123" || VAR=123
for "opt 2", 456
for "opt 3", 789
At the end, we should have:
VAR=123\|789 if "opt 1" and "opt 3" have been choosen
or
VAR=789 if only "opt 3" have been choosen.
The issue I am facing with is that my syntax to populate VAR does not work: VAR stays empty after having exited menu.
Thanx folks!

Following your approach.
You are missing to export the variable VAR in order to be available once the script has been executed.
VAR=""
PS3='Make a selection: '
options=("opt 1" "opt 2" "opt 3" "Quit")
select opt in "${options[#]}"
do
case $opt in
"opt 1")
echo "opt 1 selected"
VAR="${VAR}\|123"
;;
"opt 2")
echo "opt 2 selected"
VAR="${VAR}\|456"
;;
"opt 3")
echo "opt 3 selected"
VAR="${VAR}\|789"
;;
"Quit")
break
;;
*) echo "invalid option $REPLY"
echo $VAR ;;
esac
done
export VAR
However, export only applies to child-processes. As workaround, you can execute the script as . test.sh
Example of output:
[10:08:18][/]# . test.sh
1) opt 1
2) opt 2
3) opt 3
4) Quit
Make a selection: 1
opt 1 selected
Make a selection: 2
opt 2 selected
Make a selection: 4
[10:08:18][/]#echo $VAR
\|123\|456
You can modify the way to assign the value of the variable for having the desired output.
By adding the dot as way of execution, you are sourcing the variable. More information here: Export variable from bash

Hope this helps you a little. It's less programming than with a case in it.
#! /bin/bash
VAR=""
# Declare options and values for options
declare -A OPTIONS
OPTIONS[opt 1]="123"
OPTIONS[opt 2]="456"
OPTIONS[opt 3]="789"
echo "Options: ${!OPTIONS[#]}"
while read -r -p "Make a selection: " opt; do
# If opt becomes quit or Quit, break from loop.
! [[ $opt =~ (Q|q)uit ]] || break
if [[ ${OPTIONS[$opt]}x == "x" ]]; then
echo "$opt unknown"
else
VAR+=${OPTIONS[$opt]}
fi
done
echo $VAR
exit 0

Related

Creating Menus Shell Scripting

I'm started learning shell scripting, and I'm trying to figure out a way to add an option that returns the user back to the menu.
for example:
5) echo "Return to the menu"
echo "Return back to the menu? ";;
Hear is the script on hand:
echo "1. I'm number one"
echo "2. I'm number two"
echo "3. I'm number three"
echo "4. Exit from menu "
echo -n "Enter one the following numbers:"
while :
do
read choice
case $choice in
1) echo "You have selected the number one"
echo "Selected number is one";;
2) echo "You have selected the number two"
echo "Selected number is two";;
3) echo "You have selected the number three"
echo "Selected number is three";;
4) echo "Exiting after the information have been received by both devices" # Referring to the TCP/IP protocol. The information has to be established by both client and device to act like a server before data is sent. Ok I'm showing of here :)
exit;
esac
echo -n "Enter one of the four options"
done # Sorry if there are errors in the this code, I wrote it on the fly :)
You can also use select to create a menu
#! /bin/bash
opts=( "I'm number one" "I'm number two" "I'm number three" "Exit from menu" )
PS3="Enter one the following numbers:"
select o in "${opts[#]}"
do
case "$REPLY" in
1) echo "You have selected the number one: $o"
echo "Selected number is one";;
2) echo "You have selected the number two: $o"
echo "Selected number is two";;
3) echo "You have selected the number three: $o"
echo "Selected number is three";;
4) echo "Exiting after the information have been received by both devices" # Referring to the TCP/IP protocol. The information has to be established by both client and device to act like a server before data is sent. Ok I'm showing of here :)
exit;;
esac
done
TLDR ;) Put the usage in it's own function and call that when you want
I'd do something like this(shortened for brevity)
#!/bin/bash
printUsage() {
echo "Enter one the following options:"
echo "1: do 1 stuff"
echo "x: exit"
# add more as necessary
}
printUsage
while true; do
read choice
case $choice in
1)
echo "You have selected the number one"
break
;;
x)
echo "k thx bye"
exit
;;
*)
echo ""
echo "Invalid option: $choice"
echo ""
printUsage
;;
esac
done
echo "Doing $choice stuff"
To add a return to menu feature, try this:
Add a variable accessMenu, set it to true, and update the while loop condition as so, and set accessMenu to false first thing in the loop...
accessMenu=true
while [[ $accessMenu -eq true ]]; do
accessMenu=false
... (code)
done
Lastly, in the case that you want to enable returning to the menu, set the variable to true, and it will pass the condition in the while loop to run again.
Ok so i figured that i can wrap it up inside a function and then run the function whenever i wanted to return back to the menu.
myfunc()
{
echo "1. I'm number one"
echo "2. I'm number two"
echo "3. I'm number three"
echo "4. Return to the menu"
echo "5. Exit from menu "
echo -n "Enter one the following numbers:"
while :
do
read choice
case $choice in
1) echo "You have selected the number one"
echo "Selected number is one";;
2) echo "You have selected the number two"
echo "Selected number is two";;
3) echo "You have selected the number three"
echo "Selected number is three";;
4) echo "Return to the menu"
myfunc;;
5) echo "Exiting after the information have been received by both devices"
exit;
esac
echo -n "Enter one of the four options"
done
}
myfunc

bash - dialog command - "select all" button

The link below:
https://serverfault.com/questions/144939
It correctly shows how to create a menu using the "dialog" command but does not show how to create the "select all" shortcut button.
How to create the "Select all" button?
Like this:
#!/bin/bash
onoff=off # all unset by defaul
dialog1(){ dialog --output-fd 1 --extra-button --extra-label "Select All" --checklist "Select options:" 0 0 0 "$#"; }
dialog2(){ choices=$(dialog1 "${options[#]}"); }
set_options(){ # make options array dynamic
options=(
1 "Option 1" $onoff
2 "Option 2" $onoff
3 "Option 3" $onoff
4 "Option 4" $onoff
)
}
set_option
dialog2
case $? in # if 'Select All' presssed
3) onoff=on # set all to on
set_options # reassemble options
dialog2;; # and run dialog again
esac
clear
echo $choices
Ivan, thank you.
Taking a cue from your solution, merging it with that of the link:
https://serverfault.com/questions/144939
and improving the code in my own way, I got this solution:
#!/bin/bash
onoff=off
cmd=(dialog --output-fd 1 --separate-output --extra-button --extra-label "Select All" --cancel-label "Select None" --checklist "Select options:" 0 0 0)
load-dialog () {
options=(
1 "Option 1" $onoff
2 "Option 2" $onoff
3 "Option 3" $onoff
4 "Option 4" $onoff
)
choices=$("${cmd[#]}" "${options[#]}")
}
load-dialog
exit_code="$?"
while [[ $exit_code -ne 0 ]]; do
case $exit_code in
1) clear; onoff=off; load-dialog;;
3) clear; onoff=on; load-dialog;;
esac
exit_code="$?"
done
clear
for choice in $choices
do
case $choice in
1) echo "First Option";;
2) echo "Second Option";;
3) echo "Third Option";;
4) echo "Fourth Option";;
esac
done
sleep infinity

the select menu does not behave as it is expected

I'm new to bash. I want to have a select menu in bash. It has four options. Here is the code:
#!/bin/bash
PS3='Please enter your choice: '
while true; do
clear
options=("Option 1" "Option 2" "Option 3" "Exit")
select opt in "${options[#]}"
do
case $opt in
"Option 1")
echo "you chose choice $REPLY which is $opt"
break
;;
"Option 2")
echo "you chose choice $REPLY which is $opt"
break
;;
"Option 3")
echo "you chose choice $REPLY which is $opt"
firefox http://localhost:8000/browser/
break
;;
"Exit")
break 2
;;
*) echo "invalid option $REPLY";;
esac
done
read -p "Press [Enter] key to continue..."
done
Here is the output:
1) Option 1
2) Option 2
3) Option 3
4) Exit
Please enter your choice: 1
#you chose choice 1 which is Option 1
Press [Enter] key to continue...
This code works perfectly fine, except when I press 3. In this case after printing the message I want, the browser is opened using this command:
firefox http://localhost:8000/browser/
after opening the browser, I expect my code to display this message:
Press [Enter] key to continue...
but it doesn't until I close the browser. What's wrong?
What's wrong?
Great code!
If you want to run the process firefox in the background just add & to the end of the command.
echo "you chose choice $REPLY which is $opt"
firefox http://localhost:8000/browser/ &
break

Check for invalid input in a menu

I am making a script where the user selects a number 1-5 and it will loop until the user enters 5. I don't want to use the exit command. I wanted to check to make sure the user doesn't enter anything but 1-5 and if they do display invalid input.
any help would be appreciated
#!/bin/bash
PS3='Please enter your choice: '
options=("1.Move empty files" "2.Check file size" "3.Which files is newer" "4.File check rwx" select opt in "${options[#]}")
while($opt != 5); do
case $opt in
"Option 1")
echo "you chose choice 1"
;;
"Option 2")
echo "you chose choice 2"
;;
"Option 3")
echo "you chose choice 3"
;;
"Option 4")
echo "you chose choice 3"
;;
"Option 5")
break
;;
) echo invalid input;;
You seem confused. I don't even know where to begin correcting whatever misconceptions you have about how this works
In your original code the way you set options is unlikely to do anything useful.
options=("1.Move empty files" "2.Check file size" "3.Which files is newer" "4.File check rwx" select opt in "${options[#]}"
printf '%s\n' "${options[#]}"
This will emit
1.Move empty files
2.Check file size
3.Which files is newer
4.File check rwx
select
opt
in
The select command will not have been executed.
Here's something that does what you seem to want.
options=(
'Move empty files'
'Check file size'
'Which file is newer'
'File check rwx'
)
PS3='Please enter your choice: '
select opt in "${options[#]}" ; do
[[ -n $opt ]] && break || {
echo "invalid input"
}
done
echo "user chose '$opt'"
You could go with a while and case solution and get nearly the same results e.g.:
options=(
'Move empty files'
'Check file size'
'Which file is newer'
'File check rwx'
)
for (( i=0 ; i < ${#options[#]} ; i++ )) ; do
printf '%d) %s\n' $((i+1)) "${options[$i]}"
done
while true ; do
read -p 'Please enter your choice: ' opt
case "$opt" in
[1-5])
opt="${options[$opt]}"
break
;;
*)
echo "invalid input"
;;
esac
done
echo "user chose '$opt'"
But you don't need both and, as you can see, using select is much simpler.

Select case menu not working

I have the following select menu.
#!/bin/bash
PS3='Please enter your choice(1-4): '
options=("First Install" "Add cilent" "Delete Cilent" "Quit")
select opt in "${options[#]}"
do
case $opt in
"First Install")
newinstall
break
;;
"Add cilent")
add_client
break
;;
"Delete Cilent")
delete_client
break
;;
"Quit")
break
;;
*) echo invalid option;;
esac
done
The issue is that when i enter 2 i get invalid option message whereas all other cases work.
To avoid typos I suggest to use strings of array options only once in your code. Replace "First Install") by "${options[0]}") and "Add cilent") by "${options[1]}") etc.:
#!/bin/bash
PS3='Please enter your choice(1-4): '
options=("First Install" "Add cilent" "Delete Cilent" "Quit")
select opt in "${options[#]}"
do
case $opt in
"${options[0]}")
newinstall
break
;;
"${options[1]}")
add_client
break
;;
"${options[2]}")
delete_client
break
;;
"${options[3]}")
break
;;
*) echo invalid option;;
esac
done

Resources