I am trying to make a shell script that works as an ordering system. I have started with the first steps but it does not take the input I am not sure of what I am doing wrong. I have attached an image of what end result should be. What is the next step I should take and what should I begin to research
#!/bin/bash
clear
echo "orderBeds"
read -p "Please Enter you choice (Quit/Order)" order
if [$order -e Order|order]
then
echo "Please enter you name?"
elif [$order -e Quit|quit]
then
exit
fi
done
I'll start giving some general advice.
1) [ is a command. That means you probably don't want to expand a variable just next to it without separating them with white spaces.
2) If you will check against more than one option, use the case construct. Apart from giving you the chance of a better structure, you'll be able to use globbing expressions as options to match against.
That said, let's rewrite your code:
#! /bin/bash
clear
echo "orderBeds"
read -p "Please Enter your choice (Quit/Order)" order
case "$order" in
[Oo]rder)
read -p "Please enter your name: " name
echo "$name placed an order."
break
;;
[Qq]uit)
exit
;;
esac
the -e flag is for numerical equivalency.
Here is a corrected bash script to get you started:
#!/bin/bash
clear
echo "orderBeds"
read -p "Please enter your choice (Quit/Order) " order
if [ $order == "order" ] || [ $order == "Order" ]
then
read -p "Please enter your name " name
echo "$name placed an order"
elif [ $order == "quit"] || [ $order == "Quit" ]
then
exit
fi
Note the use of == instead of -e and the separation of the or clauses.
Related
I have a bash script that prompts the user for different information based on what they're trying to do. The prompts are usually done with read -p. Usually it works just fine, the user sees what is being asked, enters what they need to enter, and everything does what it needs to do.
See the following (sanitized) snippet of a function in the script:
#!/bin/bash
function_name() {
if [ "$this_value" == "default" ];then
echo "Value set to default."
read -p "Enter desired value here: " desired_value
desired_value=${desired_value^^}
if [ "${#desired_value}" != 3 ] ;then
echo "$desired_value is an invalid entry."
exit 1
fi
if [ "$desired_value" != "$(some command that returns something to compare against)" ];then
echo "$desired_value is an invalid entry."
exit 1
fi
read -p "You entered $desired_value. Is this correct? [y/N] " reply
reply=${reply,,}
case "$reply" in
y|yes)
$some command that does what I want it to do
;;
*)
echo "User did not enter yes"
exit 1
;;
esac
fi
}
Usually the Enter desired value here and is this correct? lines appear just fine. But in a few instances I've seen, for some reason the read prompt is just blank. A user will see the following:
./script.bash
##unrelated script stuff
##unrelated script stuff
Value set to default.
user_entered_value_here
User did not enter yes. Exiting.
This is a real example that just happened that finally made me come here to ask what is going on (and I modified appropriately to make it an SO post).
What's happening is these two blank lines appear instead of the read -p text. For the first one, the user entered user_entered_value_here because they already know what is supposed to be entered there even without the read prompt. The second one, the Y/N prompt, they don't know, so they see it apparently hanging, and hit Enter instead of y, causing it to trigger the * case option.
I don't understand why the read -p text is not appearing, and especially why it's appearing for most users but not all users. I suspect there's some kind of environmental setting that causes this, but for the life of me I can't figure out what. This is being run only on RHEL 6.2, under bash 4.1.2.
I looked at the man of bash to catch some kind of detail about the read built-in. It is specified that -p option displays the "prompt on standard error, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal".
Let's consider the simple script input.sh:
#!/bin/bash
read -p "Prompt : " value
echo The user entered: "$value"
Example of execution:
$ ./input.sh
Prompt : foo
The user entered: foo
If stderr is redirected:
$ ./input.sh 2>/dev/null
foo
The user entered: foo
If the input is a pipe
$ echo foo | ./input.sh
The user entered: foo
If the input is a heredoc
$ ./input.sh <<EOF
> foo
> EOF
The user entered: foo
Rewrote your script with shell agnostic grammar and fixed some errors like comparing the string length with a string comparator != = rather than a numerical comparator -ne -eq:
#!/usr/bin/env sh
this_value=default
toupper() {
echo "$1" | tr '[:lower:]' '[:upper:]'
}
function_name() {
if [ "$this_value" = "default" ]; then
echo "Value set to default."
printf "Enter desired value here: "
read -r desired_value
desired_value=$(toupper "$desired_value")
if [ "${#desired_value}" -ne 3 ]; then
printf '%s is an invalid entry.\n' "$desired_value"
exit 1
fi
if [ "$desired_value" != "$(
echo ABC
: some command that returns something to compare against
)" ]; then
echo "$desired_value is an invalid entry."
exit 1
fi
printf 'You entered %s. Is this correct? [y/N] ' "$desired_value"
read -r reply
reply=$(toupper "$reply")
case $reply in
'y' | 'yes')
: "Some command that does what I want it to do"
;;
*)
echo "User did not enter yes"
exit 1
;;
esac
fi
}
function_name
I have a $empIc which is a variable input by the user. I try to read some details from a text file and do checking on variable $ic. If the input does not match, script file invalidic will be executed where it let the user to choose to reenter the input or back to menu. However, the read command in the invalidic script is never executed and resulted in an infinite loop.
while IFS=':' read -r dep ic name phone email gender birthDate jobTitle joinDate
do
if [ "$empIc" = "$ic" ]
then
echo -n "Employee Name : $name"; echo
echo -n "Job Title : $jobTitle"; echo
echo -n "Department : $dep"; echo
break
else
match=0
fi
case $match in
0) echo "No such record!"; ./invalidic; break;;
*)
esac
done <Employee.txt
This is the code for invalidic script file:
#!/bin/bash
while true
do
echo "========================================="
echo "1. Enter Performance Review again"
echo "2. Back to Human Resource Management Menu"
echo "========================================="
echo "What would you like to do? Please enter choice in number: "; read action
case $action in
1) ./task4_main; break;;
2) ./task1_menu; break;;
*) echo "Please enter 1 for Performance Review, 2 to back to Human Resource Management Menu"
esac
done
This is the output I get when the input does not match with data stored
The immediate problem is that invalidic is run inside the while ... read ... done <Employee.txt loop, so it's reading from the Employee.txt file instead of the terminal. But that's a result of another problem: you presumably want to run invalidic if there's no match for $empIc in the Employees.txt file, but the current script runs it if the first line in Employees.txt doesn't match. It also sort-of tries to run it for each and every non-matching line, but since it never gets past the first one that doesn't happen.
You need to wait until the loop has finished checking each line in the Employees.txt file, and if it gets to the end of that without finding a match then you should run invalidic. That is, do something like this:
match=0 # No match found *yet*, because we haven't started looking
while IFS=':' read -r dep ic name phone email gender birthDate jobTitle joinDate
do
if [ "$empIc" = "$ic" ]
then
echo "Employee Name : $name" # Don't use `echo -n`, then `echo` to add a newline. Just skip the -n
echo "Job Title : $jobTitle"
echo "Department : $dep"
match=1 # Found a match
break
fi
done <Employee.txt
# If we *still* haven't found a match (now that we've now scanned the
# entire file) then there isn't a match there.
case $match in
0) echo "No such record!"; ./invalidic;;
*)
esac
Actually, I'd replace that last case with a simple if [ "$match" = 0 ] -- you don't need the power and complexity of case here, and IMO an if is the better choice.
Note: I'm also a bit worried that you're using script execution like GOTOs. Inside invalidic, you can run either task4_main or task1_main, both of which sound like main tasks, not subtasks of an invalid ID handler. When you run something like ./somescript, you really should be running a subtask, not just that that's the next logical thing to do.
I'm trying to make a shell script (.sh) on my mac, but somehow I can't get the 'read' function to work. This is my code:
READ -p "What now? " var
ECHO $var
ECHO " "
if [ "$var" == "getfiles" ]
then
ECHO "Test1"
elif [ "$var" == "help" ]
then
ECHO "Test2"
else
ECHO "Please enter a valid command (type 'help' for a list of valid commands)"
fi
As you can see, I'm trying to get user input by using 'READ -p "What now? " var'. However, no matter what I type, it returns an empty variable. I've searched everywhere, but no one seems to have the same problem as I do. I checked the code a thousand times, but can't find any irregularities. Can anyone see what I'm doing wrong? Thanks in advance.
Use lowercase read and echo.
echo "${var}"is better than echo $var
I'm trying to write a program where the program will ask you your name, confirm that you want this name, then check to see if you said yes or no. I have the "no" loop working, where it will ask for a name again, but I'm trying to a loop where if you type anything other than yes or no it will say "Please type yes or no." then ask if you want to confirm your name, then check the answer again. Heres what I have.
echo -e $WHITE"Name your$GREEN Hero$WHITE."
read HERO
clear
echo -e "Are you sure you want your$GREEN Hero$WHITE's name to be$GREEN "$HERO"$WHITE? y/n"
read ANSWER1
while [ $ANSWER1 = "no" ]; do
#
#
#
clear
echo -e $WHITE"Name your$GREEN Hero$WHITE."
read HERO
clear
echo -e "Are you sure you want your$GREEN Hero$WHITE's name to be$GREEN "$HERO"$WHITE? y/n"
read ANSWER1
done
while [ $ANSWER1 != "yes" ] || [ $ANSWER1 != "no" ]; do
#
#
#
clear
echo -e $WHITE"Please type yes or no."
sleep 1.5
clear
echo -e $WHITE"Are you sure you want your$GREEN Hero$WHITE's name to be$GREEN "$HERO"$WHITE?"
read ANSWER1
clear
done
clear
echo -e -n $WHITE"Loading"
sleep 1.5
echo -e -n "."
sleep 1.5
echo -e -n "."
sleep 1.5
echo -e -n "."
sleep 1.5
clear
echo -e "Done."
If I go through the "Please type yes or no." it will freeze at the sleep and not clear, therefore not displaying the echo and continuing the loop. Any help or suggestions would be greatly appreciated!
Here's the problem:
while [ $ANSWER1 != "yes" ] || [ $ANSWER1 != "no" ]; do
Every possible answer is different to at least one of them. There's no string that's equal to yes and no at the same time. You need && instead of ||.
An easier way to write a loop to get user's input is the select command:
while true; do
read -p "${white}Name your ${green}Hero$white: " hero
echo "Are you sure you want your ${green}Hero$white's name to be $green\"$hero\"$white? "
select ans in Yes No; do
case $ans in
Yes) break 2 ;; # break out of both select and while loops
No) break ;; # only break out of select loop
esac
done
done
echo "Your ${green}Hero$white's name is $green\"$hero\"$white."
In my program, I have to check whether a command given as a input by a user exists or not and if it exists, program needs to check if the parameters of that command are correct.
For example:
ls ( is correct)
-al (is correct)
do the watch
and if I do this:
ls (is correct)
-kala (not correct)
don't do the watch.
How I can do this? Here is my script:
while true
do
echo "Insert the command"
read comm
if [ "$(type -t $comm)" != "" ]; then
echo "Insert the parameters of the command ";
read par;
echo "Insert the time of watch";
read time;
if [ $t -le 0 ]; then
echo "Value not correct";
else
clear;
while true
do
echo "$comm"
date
echo ""
$comm $par
sleep $((time))
clear
done
fi;
else
echo "Command not found, retry.";
echo "";
fi
done
You can replace the command invocation with this:
if ! $comm $par; then
exit 1
fi
to make it stop after an error. Also there is already a tool called watch but I think you already know this.