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
Related
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
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.
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
I have an options menu function:
function()
{
echo "1 Option 1"
echo "2 Option 2"
echo "3 Option 3"
echo "q Exit"
read -p "Select 1-3 ή \"q\" to quit: " i
case "$i" in
1)
echo "option 1"
echo;;
2)
echo "option 2"
echo;;
3)
echo "option 3"
echo;;
q) echo -e "\033[01;33mexit!!!\033[39m"
sleep 1
clear
exit ;;
*)
echo "Unknown command"
read -s -n 1 -p "Press any key to continue…"
echo
esac
}
while:
do function
done
The above works fine, but need to press enter after I input the number before the command run. Is there any way to immediately run the command when I press the key?
You've got the answer right in your sample code (in the second read). You want to take advantage of bash's read -n 1 capability (note, this is not POSIX compliant, so it won't reliably work in /bin/sh unless that happens to map to bash):
read -n 1 -p "Select 1-3 ή \"q\" to quit: " i
Im having a problem with my unix code
#!/bin/bash
while : ; do
echo "SELECT OPTION"
echo "-------------"
echo "1- Create username"
echo "2- Create password"
echo "3- Delete username"
echo "4- Exit"
read -p "enter option 1 2 3 or 4:" option
case option in
1) read -p "Enter username:"
adduser $REPLY && echo "Username successfully entered" ;;
2) passwd && "Password successfully entered" ;;
3) read -p "Enter user to be deleted: "
deluser $REPLY && echo "User deleted" ;;
4) exit ;;
*) continue ;;
esac
done
Ok the select option works, but if i type in 1 or 2 as an option to create username or password, its takes me back to the select options again. Whatever i do press it will always show the select option
Can someone help me run this code in unix using bash.
Thank You
Try $option - option gets interpreted as a string.