Bash shell, Adding a variable number of variables - bash

I am trying to write a short script that accepts a variable number of parameters (also numbers)
then adds those parameters together to get a total of the numbers. Then gets an average for those numbers entered.
This is what i have so far;
#!/bin/bash
count=1
ncount=1
echo
echo "please enter number of parameters: "
read parano
while [ $parano -ge $numbers$count ]
do
echo
echo "Please enter parameter $count: "
read number$ncount
let count=count+1
let ncount=ncount+1
done
Total=$((number$ncounttotal))
Average=$((Total/parano))
echo
echo "You have chosen $parano parameters"
echo
echo "The average is $Average"
echo
Its just the line for calculating the total that I am having issues with and cannot seem to find the code to calculate it. The rest seems to be working great but the average always comes out as 0 because of the total not being calculated.
Anyone have any ideas?

#!/bin/bash
[ $# -eq 0 ] && exit 1
for number in $#; do
sum=$(($sum + $number))
done
average=$(echo "$sum / $#" | bc -l)
echo $average
Then call it like:
./shellscript 1 2 3
I use bc above since bash will only do integer arithmetic and that's not great for the average.

Thank you for the help guys. The answer to what I needed was an array as mentioned.
#!/bin/bash
echo
echo "Please enter number of parameters: "
read parano
count=1
Total=$((0))
while [ $parano -ge $numbers$count ]
do
echo
echo "Please enter parameter $count: "
read number
let count=count+1
Total=$(($Total+number))
done
Average=$((Total/parano))
echo
echo "You have chosen $parano parameters"
echo
echo "The total is $Total "
echo
echo "The average is $Average"
echo
Answer was to make an array as the total and keep adding the variables to the array as they went along. At least that's what I think it is. Either way it works so thanks all!

Related

what code function will help to ask for input when i try to execute a code with no previous value in shell script

When I choose Option 3 after opening the file it just terminates.
I was trying to use if else function inside section 3 where it ask for new values if there is none stored so that instead of terminating it will ask for values but cant seem to work it out.
#!/bin/bash
while : #This program demonstrate 4 option below
do
clear
echo "Main Menu"
echo "Select any option of your choice"
echo "[1] Show Todays date/time,Files in current directory,home
directory,user id "
echo "[2] Enter a range "
echo "[3] Highest and lowest of the eight random numbers "
echo "[4] Exit/Stop "
echo "==========="
echo -n "Menu choice [1-4]: "
read -r yourch #Choose option out of 4
case $yourch in
1) echo "Today is";date;
echo "Your home directory is:";home;
echo "Your path is :";PWD;
echo "Current Shell";uname;
echo "Your Student ID $USER ID ";
echo "Press a key...";read -r;;
2) echo "Lower value" #Enter the lower value
read -r s1
echo "Higher value" #Enter the higher value
read -r s2
dif=$((s2-s1))
if [ $dif -ne 100 ]
then
echo "Range should be 100"
else #if the differnce is 100 then programe run otherwise terminates
in=$( ("$s2" - "$s1")) #formula for the range
echo "8 random numbers between $s1 and $s2 are :-"
for i in $(seq 1 8)
do
t=$( ($RANDOM % "$in"))
n=$( ("$t" + "$s1"))
echo "$n" #Here we get the random numbers
done
fi
echo "Press a key..."; read -r;;
3) diff=$((s2 - s1)) #Depicts Highest and lowest numbers of the randoms
RANDOM=$$
min=9999
max=-1
for i in $(seq 8)
do
R=$((((RANDOM%diff))+s1))
if [[ "$R" -gt "$max" ]]
then
max=$R
fi
if [[ "$R" -lt "$min" ]]
then
min=$R
fi
done
echo "Biggest number and smallest numbers are $max and $min" #Prints the highest and lowest numbers
echo "press a key...";read -r;;
4)echo " THANK YOU VERY MUCH $ Good Bye"
exit 0;; #Exit command
*)echo "Opps!!! Please select choice 1,2,3,4";
echo "press a key...";read -r;;
esac
done
I would like for it to ask for new values if there is no previous data stored.
I checked your script, to see the problem. It terminates with a division by zero, because s1 and s2 initially are not set. To resolve this, you can use code like
if [ -z "${s1}" ] ;then
read -p "s1 is empty, please enter a number " s1
fi
if [ -z "${s2}" ] ;then
read -p "s2 is empty, please enter a number " s2
fi
-z "..." is true, if the string is empty. The shell doesn't distinguish data types and because I use the doublequotes it is safe to check for an empty string because if s1 is not set, "$s1" results in an empty string.
Btw. "$s1" is logically equivalent to "${s1}", but it is safer to use the curly braces, because there are no ambiguities this way where the variable ends. For example consider the lines:
year=90
echo "I like the music of the $years"
#
echo "I like the music of the ${year}s"
The first echo outputs "I like the music of the" unless variable "years" was set before, while the second outputs "I like the music of the 90s". Without curly braces this would be a bit more inconvenient. Without curly braces sometimes you might run in such ambiguities, without recognizing it easily.

Unix Scripting - Finding Minimum and Maximum (Bash Shell)

My code below is part of an assignment, but I'm racking my head against the desk not understanding why it won't assign a "MIN" value. I tried assigning the MIN and MAX to ${LIST[0]} just to have the first index in place, but it returns the whole array, which doesn't make sense to me. I'm executing this on a CentOS VM (which I can't see making a difference). I know the beginning of the first and second "if" statements need better logic, but I'm more concerned on the MIN and MAX outputs.
#!/bin/bash
LIST=()
read -p "Enter a set of numbers. " LIST
MIN=
MAX=
if [ ${#LIST[*]} == 0 ]; then echo "More numbers are needed."; fi
if [ ${#LIST[#]} -gt 0 ]; then
for i in ${LIST[#]}; do
if [[ $i -gt $MAX ]]; then
MAX=$i
fi
if [[ $i -lt $MIN ]]; then
MIN=$i
fi
done
echo Max is: $MAX.
echo Min is: $MIN.
fi
The code is almost functional.
Since $LIST is an array, not a variable, change read -p "Enter a set of numbers. " LIST to:
read -p "Enter a set of numbers. " -a LIST
Move the $MIN and $MAX init code down 5 lines, (just before the for loop):
MIN=
MAX=
...and change it to:
MIN=${LIST[0]}
MAX=$MIN
And it'll work. Test:
echo 3 5 6 | ./minmax.sh
Output:
Max is: 6.
Min is: 3.

bash - how to put $RANDOM into value?

newbie to bash:
basically I want to compare the result of $RANDOM to another value which is given by the user through 'read'
code for more info:
echo $RANDOM % 10 + 1 | bc
basically I want an if statement as well to see if the result of that $RANDOM value is equal to something that the user typed in e.g.:
if [ [$RANDOM VALUE] is same as $readinput
#readinput is the thing that was typed before
then
echo "well done you guessed it"
fi
something along the lines of that!!
to summarise
how do i make it so that i can compare a read input value to echo "$RANDOM % 10 + 1 | bc"
think of the program I am making as 'GUESS THE NUMBER!'
all help VERY MUCH APPRECIATED :)
There's no need for bc here -- since you're dealing in integers, native math will do.
printf 'Guess a number: '; read readinput
target=$(( (RANDOM % 10) + 1 )) ## or, less efficiently, target=$(bc <<<"$RANDOM % 10 + 1")
if [ "$readinput" = "$target" ]; then
echo "You correctly guessed $target"
else
echo "Sorry -- you guessed $readinput, but the real value is $target"
fi
The important thing, though, is the test command -- also named [.
test "$readinput" = "$target"
...is exactly the same as...
[ "$readinput" = "$target" ]
...which does the work of comparing two values and exiting with an exit status of 0 (which if will treat as true) should they match, or a nonzero exit status (which if will treat as false) otherwise.
The short answer is to use command substitution to store your randomly generated value, then ask the user for a guess, then compare the two. Here's a very simple example:
#/bin/bash
#Store the random number for comparison later using command substitution IE: $(command) or `command`
random=$(echo "$RANDOM % 10 + 1" | bc)
#Ask the user for their guess and store in variable user_guess
read -r -p "Enter your guess: " user_guess
#Compare the two numbers
if [ "$random" -eq "$user_guess" ]; then
echo "well done you guessed it"
else
echo "sorry, try again"
fi
Perhaps a more robust guessing program would be embedded in a loop so that it would keep asking the user until they got the correct answer. Also you should probably check that the user entered a whole number.
#!/bin/bash
keep_guessing=1
while [ "$keep_guessing" -eq 1 ]; do
#Ask the user for their guess and check that it is a whole number, if not start the loop over.
read -r -p "Enter your guess: " user_guess
[[ ! $user_guess =~ ^[0-9]+$ ]] && { echo "Please enter a number"; continue; }
#Store the random number for comparison later
random=$(echo "$RANDOM % 10 + 1" | bc)
#Compare the two numbers
if [ "$random" -eq "$user_guess" ]; then
echo "well done you guessed it"
keep_guessing=0
else
echo "sorry, try again"
fi
done

How to use expr with echo and $

#!/bin/bash
echo "Please enter a number that can divided by 5"
read input
ans= 'expr $input/5'
echo "$ans"
So i want this code to be something like this, a user will enter a number that can divided by 5 (5,10,15,20 etc etc) and then it will echo the answer, i am not sure whats wrong with my code it keeps saying "no such file or directory " for output not sure how to fix that.
I think the spaces were your problem...
#!/bin/bash
echo "Please enter a number that can divided by 5"
read input
ans=`expr $input / 5`
echo "$ans"

Count down with until

I get the issue when I give the user an option to enter a number, that number is going to be counted down to 1. I'm lost after the echo line, as the script echos the value entered but doesn't count it down to 1.
#!/bin/bash
COUNTER=100
until [ $COUNTER -lt 1 ]; do
read -p "Enter a number between 1-100: " COUNTER
echo COUNTER $COUNTER
let COUNTER-=1
done
Move the read out of the loop like this:
read -p "Enter a number between 1-100: " COUNTER
until [ $COUNTER -lt 1 ]; do
echo COUNTER $COUNTER
let COUNTER-=1
done
Try doing this using modern bash :
#!/bin/bash
read -p "Enter a number between 1-100: " counter
until ((counter < 1)); do
echo "counter $counter"
((counter--))
done
put read outside of the for loop to do it successfully.
avoid using UPPER CASE variables by default, there's reserved for global system variables.
((...)) is more intuitive than -gt, -lt... and is an arithmetic command, which returns an exit status of 0 if the expression is nonzero, or 1 if the expression is zero. Also used as a synonym for "let", if side effects (assignments) are needed. See http://mywiki.wooledge.org/ArithmeticExpression

Resources