I would like to create a menu in shell script with a range of options. In this case, I want to force the user only to use a range of numbers, e.g. 1 to 5, but without use CASE. If the user choose 6, the menu ask again for the number between the range.
I remember something like:
OPTION (){
[[ $option = +(1|2|3|4|5) ]] || OPTION
}
Following may help you in same:
cat choose2.ksh
check() {
while [ ! ${finished} ]
do
echo "Please enter a digit:"
read value
if [[ $value -le 5 ]]
then
echo "user entered between 1 to 5."
finished=1
else
echo "user entered more than 5 in this case."
fi
done
}
check
Execution of script:
./choose2.ksh
Please enter a digit:
12
user entered more than 5 in this case.
Please enter a digit:
12
user entered more than 5 in this case.
Please enter a digit:
1
user entered between 1 to 5.
So you could see that if user enters other than 1 to 5 than it asks user again a Input else it will simple come out of script(you could do other things too as per your need).
Related
This question already has answers here:
Brace expansion with variable? [duplicate]
(6 answers)
Closed 3 years ago.
I need to get user input for a number and then write a name row by row in linux terminal that much amount of times that user inputed. Example if I lets say chose a number 2 the program will write Name 2 times row by row. I wrote some code but I cant figure where is the mistake. I think its the loop where the mistake is.
echo "Please enter a number "
read $number
for value in {$number}
do
echo "Name"
done
To read input and save it into a variable named number, do:
read number
To get the value of number, do $number or ${number}. Remove the { } in the {$number} or shift $ with {.
Just do:
echo "Please enter a number "
read number
if ! test "$number" -gt 0 2> /dev/null; then
echo "You must enter an integer greater than 0" >&2
exit 1
fi
yes Name | sed ${number}q
But don't prompt for the number. Take it as a command line argument, and just do
yes Name | sed "${1}q"
Let sed generate the error message if the parameter is invalid.
The trouble with your loop is that for value in $number takes the string $number and breaks it on whitespace (depends on IFS, actually, but let's not get bogged down by details) and iterates over each value. That is, if $number is the string 1 3 dog 5, then the loop will iterate 4 times with $value taking the values 1, 3, dog, and 5. If $number is 7, then the loop iterates exactly once. You could do for((i=0; i < $number; i++)); do ..., but that does not generate any useful error message if $number is not an integer.
I have the following code to loop through a question session with a user:
#loop counter
COUNTER=1
# Initial question
echo ""
echo -n "Would you like a cup of tea? (y/n)" # Ask initial question
read answer # Check answer
while [ $COUNTER -le 5 ] # while counter is less than or equal to 5
do
if [ "$answer" != "${answer#[Yy]}" ]; then # if answer is 'y'
echo "" # skip a line for cleanliness
echo "Great, I'll make it now" # Satisfaction
echo ""
break # End the loop
else # if answer is anything other than 'y'
echo "" # skip a line for cleanliness
echo -n "Are you sure? (y/n)" # Ask again
read answer # Check the answer again
let COUNTER=COUNTER+1 # increment COUNTER
fi
done # finish
The code should act as follows:
Ask user if they would like tea.
If user says yes, then print out something, and end loop
If user says no, go for another 4 attempts before ending loop.
If user says yes, after saying no, print out something, and end loop.
The code works fine for points 1,2, and 4.
On point 3 - the code loops to a 5th loop before ending.
I can't seem to be able to identify the error.
Edit: Changed to COUNTER = 0, and $COUNTER -le 4. However, code doesn't implement point 4, on 4th attempt (i.e. 1 initial no, followed by 3 extra nos, before a yes).
You could simply limit counter to less than 5, instead of less than or equal to.
Use -lt instead of -le. That is [ $COUNTER -lt 5]
OR
You can say less than or equal to 4 and thus you can maintain [ $COUNTER -le 4]
Instead of having 2 lines,
echo -n "Are you sure? (y/n)" # Ask again
read answer # Check the answer again
you can shorten it to one:
read -p "Are you sure? (y/n): " answer
However, I'm not entirely sure by what you mean by point 4. Could you provide an example or a little more description?
Welcome all,
I am required to prompt the user to enter "all, long, human or alh". I have developed some code however there is an error. I have used shellcheck.net to check whether the syntax of my code is appropriate.
the program itself should give a file and directory listing (based on the command line parameter received) and also show an error message if one of the options above is not selected.
”all” - do not hide entries starting with .
“long” - use a long listing format
“human” - use a long listing format and print sizes in human readable
format
“alh” – do all of the above
This is my code:
read -p "Please enter all, long, human or alh: " userInput
if [ -z "$userInput" ];
then
print f '%s/n' "Input is not all, long human or alh"
exit 1
else
printf "You have entered %s " "$UserInput"
fi
the code itself works, however it does not show any directory listings based on the chosen parameter.
Output:
Please enter all, long, human or alh: all
You have entered all
I'd use the case command
#!/bin/bash
read -p "Please enter all, long, human or alh: " userInput
case "$userInput" in
(all) flags=a;;
(long) flags=l;;
(human) flags=lh;;
(alh) flags=alh;;
(*) printf '%s\n' "Input is not all, long human or alh"
exit 1;;
esac
ls -$flags
Or, you can store the flags in an associative array:
#!/bin/bash
read -p "Please enter all, long, human or alh: " userInput
declare -A flags
flags=([all]=a
[long]=l
[human]=lh
[alh]=alh
)
flag=${flags[$userInput]}
if [[ -z $flag ]] ; then
printf '%s\n' "Input is not all, long human or alh"
exit 1
fi
ls -$flag
As the title says, I'm trying to make a program that has a user input a number 1-7, then displays the appropriate command for each number.
The problem I'm having is finding a good way to set each number to a command.
At first, I thought about doing something like this.
OSI=$(uname -a)
echo $OSI
But the problem with that is actually implementing it into a loop. Let's say the user is prompted like so:
"Enter a number:"
The user enters the number 1, and number 1 is the OSI. Well if a user picks the number 2, it needs to display a different command and so forth.
This is a little bit too complicated for a beginner like myself. I've read through forums and different posts, but I cannot figure out the right commands to make this happen.
I tried doing something like this and it failed miserably:
#!/bin/bash
read -p "Enter a number:" n1 n2 n3 n4 n5 n6 n7
if n1=1; then
uname - a
else n2=2; "different command"
fi
I realize I'm completely garbage at bash. I'm not asking for anyone to solve this, just give me some pointers in a way that makes sense to me.
Thanks.
Give this tested version a try:
#!/bin/bash --
printf "menu items:\n 1) uname -a\n 2) date\n q) exit\n"
read -p "Enter your choice: " response
if [ -z "$response" ] ; then
printf "Choice invalid\n"
exit 1
fi
if [ "$response" = q ] ; then
exit 0
fi
if [ "$response" = 1 ] ; then
uname -a
elif [ "$response" = 2 ] ; then
date
else
printf "Choice invalid\n"
fi
As written by #EdMorton case is a better option.
My bash script asks user for their first name, last name, address and phone number and writes this information that is input by the user to a file of the format "firstname.lastname"; however I want to repeat this a number of times (I actually wanted to do something like a do..while loop where it runs atleast one time and asks user if they want to continue creating accounts or not but I see there is no do...while for bash it seems). So when I execute this bash script in the terminal it will ask for how many accounts to be made and I provide all the input but the it only runs one time. What am I doing wrong? Here is my script.
#!bin/bash
echo "How many accounts are you creating?"
read num
echo "Enter first name"
read fName
echo "Enter last name"
read lName
echo "Enter address"
read add
echo "Enter phone number"
read phn
echo "Enter gender m for male and f for female"
read gender
if [ "$gender" == "m" ]
then
sex="male"
elif [ "$gender" == "f" ]
then
sex="female"
else
echo"Invalid gender. Restart the script and enter a valid gender"
exit 0
fi
for (( i = 0; i<=num; i++))
do
cat > $fName.$lName <<-EOF
Full Name: $fName $lName
Address: $add
Phone number: $phn
Gender: $gender
EOF
done
zerobandwidth's answer is correct, but as an alternative answer, it is in fact quite easy to do what you initially wanted to do:
while true; do
# Your account creation code goes here
echo "Create another account (y/n)?"
read another
if [ "$another" != y ]; then
break
fi
done
Put your input code inside the loop, or wrap that code in a function and call the function inside the loop.