For loop structure to add in bash - bash

I'm new to this and what I'm trying to do is create a simple adding script in bash.
I have to use a for loop. What I'm starting so far looks like this:
#!/bin/bash
sum=0
for num in {1..15}
do
echo $num
done
echo$sum
I need help with how to make the for loop show for example if I type:
add 4 -3 2 8
it will output as:
4
-3
2
8
=11
How would I make it so the $num only show what I typed in such as the '4 -3 2 8' and negative numbers?

You can use $# to get all parameters, and $(()) to do arithmetic.
sum=0
for num in $#
do
sum=$((sum + num))
done
echo $# = $sum
I'll retag your question as bash; d is not appropriate.

I'm trying to create an exit error to expand on the previous script now. if I type anything but a number now and what I have tried so far is:
sum=0
for num in "$#"
do
echo $num | grep -i [^0-9+-]
if ["$?" = 1] then
echo "Sorry, '$num' is not a number"
fi
sum=$((sum + num))
done
echo $sum
Example if I type in
add 1 2 3 four five
it would say
four
Sorry, 'four' is not a number

Related

Bash syntax errors like `syntax error: operand expected (error token is "{1 % 2 ")`

Please tell why printing odd numbers in bash script with the following code gives the error:
line 3: {1 % 2 : syntax error: operand expected (error token is "{1 % 2 ")
for i in {1 to 99}
do
rem=$(( $i % 2 ))
if [$rem -neq 0];
then
echo $i
fi
done
This is working example:
for i in {1..99}
do
rem=$(($i % 2))
if [ "$rem" -ne "0" ]; then
echo $i
fi
done
used for loop have a typo in minimum and maximum number, should be {1..99} instead of {1 to 99}
brackets of the if statement needs to be separated with whitespace character on the left and on the right side
Comparision is done with ne instead of neq, see this reference.
As already pointed out, you can use this shell checker if you need some clarification of the error you get.
Not really sure why nobody included it, but this works for me and is simpler than the other 'for' solutions:
for (( i = 1; i < 100; i=i+2 )); do echo $i ; done
To print odd numbers between 1 to 99
seq 1 99 | sed -n 'p;n'
With GNU seq, credit to gniourf-gniourf
seq 1 2 99
Example
$ seq 1 10 | sed -n 'p;n'
1
3
5
7
9
if you reverse it will print even
$ seq 1 10 | sed -n 'n;p'
2
4
6
8
10
One liner:
for odd in {1..99..2}; do echo "${odd}"; done
Or print in a cluster.
for odd in {1..99..2}; do echo -n " ${odd} "; done
Likewise, to print even numbers only:
for even in {2..100..2}; do echo "${even}"; done
OR
for even in {2..100..2}; do echo -n " ${even} "; done
Replace {1 to 99} by {1..99}.
for (( i=1; i<=100; i++ ))
do
((b = $i % 2))
if [ $b -ne 0 ]
then
echo $i
fi
done
for i in {1..99}
do
rem=`expr $i % 2`
if [ $rem == 1 ]
then
echo "$i"
fi
done
for i in {0..49}
do
echo $(($i*2+1))
done

Bash Script accepting a number, then printing a set of int from 0 to the number entered

I am trying to write a bash script that accepts a number from the keyboard, and then prints a set of integers from 0 to the number entered. I can't figure out how to do it at all.
This is my code:
while [ 1 ]
do
echo -n "Enter a color: "
read user_answer
for (( $user_answer = $user_answer; $user_answer>0; $user_answer--))
echo $user_answer
fi
done
exit
The error I'm recieving is:
number_loop: line 10: syntax error near unexpected token echo'
number_loop: line 10: echo $user_answer'
Assign a separate variable in order to use increment/decrement operators. $user_answer=$user_answer will always be true and it will throw an error when trying to use decrement. Try the following :
#!/bin/bash
while [ 1 ]
do
echo -n "Enter a color: "
read user_answer
for (( i=$user_answer; i>0; i-- ))
do
echo $i
done
done
exit
You missed the do statement between your for and the echo.
bash has many options to write numbers. What you seem to be trying to do is easiest done with seq:
seq $user_answer -1 0
If you want to use your loop, you have to insert a ; do and replace the fi with done, and replace several $user_answer:
for (( i = $user_answer; i>0; i--)); do
echo $i
done
(btw: I assumed that you wanted to write the numbers in reverse order, as you are going backwards in your loop. Forwards is even easier with seq:
seq 0 $user_input
)
This is where a c-style loop works particularly well:
#!/bin/bash
for ((i = 1; i <= $1; i++)); do
printf "%s\n" "$i"
done
exit 0
Example
$ bash simplefor.sh 10
1
2
3
4
5
6
7
8
9
10
Note: <= is used as the for loop test so it 10 it iterates 1-10 instead of 0-9.
In your particular case, iterating from $user_answer you would want:
for (( i = $user_answer; i > 0; i--)); do
echo $i
done
The for loop is a bash internal command, so it doesn't fork a new process.
The seq command has a nice, one-line syntax.
To get the best of the twos, you can use the { .. } syntax:
eval echo {1..$answer}

Shell script I am trying to get the product of odd numbers

mul=1
i=0
while [ $i -ne 10 ]
do
echo "Enter Number"
read num
if [ `expr $num % 2` -ne 0 ]
then
mul=`expr $mul*$num`
fi
i=`expr $i + 1`
done
echo mul of odd numbers = $mul
this is what i tried...its showing output as 1*3*5*7*9
pls correct the error here
Thanks in advance
"*" has a special meaning, hence you need to escape it and need to have a space between the two variables like:
mul=`expr $mul \* $num`
Note aside- Use of back ticks are discouraged and you may want to use something instead like:
mul=$(expr $mul \* $num)
Since your don't provide some details (see my comment above) I can't guarantee this answers your question and produces the desired result. This assumes your shell is bash. Please inform me and I'll edit the answer accordingly.
Consider the changes below. The relevant part is the change from expr ... to $(( ... )), which is bash's built-in arithmetic expression evaluator.
#!env bash
MUL=1
I=0
while [ $I -ne 10 ]
do
echo "Enter Number"
read NUM
if [[ $(($NUM % 2)) -ne 0 ]] ; then
MUL=$(($MUL * $NUM))
fi
I=$(($I + 1))
done
echo MUL of odd numbers = $MUL
This produces the following output:
$ sh foo.sh
Enter Number
1
Enter Number
2
Enter Number
3
Enter Number
4
Enter Number
5
Enter Number
6
Enter Number
7
Enter Number
8
Enter Number
9
Enter Number
0
MUL of odd numbers = 945

For loop in shell script with integer as input

I am trying to take integer as a input and trying to print numbers from 1 to the input number.
How can I do that?
Something like this will work:
read -p "Loop until: " n
for i in $(seq 1 $n); do
echo $i;
done
$n will contain the user input.
The seq program simply builds a sequence of numbers from 1 to $n, and the for loop prints every item in this sequence.
Instead of using seq command you can use the arithmetic initialisation in a shell.
You can use the following code to do it.
$ cat test
#!/bin/bash
read -p "Loop until: " n
a=1
while true; do
if [ $a -le $n ]; then
echo $a
else
break
fi
a=$(($a+1))
done
$ sh test
Loop until: 4
1
2
3
4

Is it possible to use a variable in for syntax in bash?

I wonder If it is possible to write "for i in {n..k}" loop with a variable.
For example;
for i in {1..5}; do
echo $i
done
This outputs
1
2
3
4
5
On the other hands
var=5
for i in {1..$var}; do
echo $i
done
prints
{1..5}
How can I make second code run as same as first one?
p.s. I know there is lots of way to create a loop by using a variable but I wanted to ask specifically about this syntax.
It is not possible to use variables in the {N..M} syntax. Instead, what you can do is use seq:
$ var=5
$ for i in $(seq 1 $var) ; do echo "$i"; done
1
2
3
4
5
Or...
$ start=3
$ end=8
$ for i in $(seq $start $end) ; do echo $i; done
3
4
5
6
7
8
While seq is fine, it can cause problems if the value of $var is very large, as the entire list of values needs to be generated, which can cause problems if the resulting command line is too long. bash also has a C-style for loop which doesn't explicitly generate the list:
for ((i=1; i<=$var; i++)); do
echo "$i"
done
(This applies to constant sequences as well, since {1..10000000} would also generate a very large list which could overflow the command line.)
You can use eval for this:
$ num=5
$ for i in $(eval echo {1..$num}); do echo $i; done
1
2
3
4
5
Please read drawbacks of eval before using.

Resources