conditional execution of steps after called function in bash - bash

Requirement: Based upon IF condition in the called function: myfunc, echo hello in the for loop should not get executed and control should go to the next iteration.
In the below script, when the value of k becomes 2 and 3, echo hello should not get executed.
This is the script that I am trying to develop but no success.
#!/usr/bin/env bash
myfunc() {
if [[ $k -gt 1 ]]; then
echo "in the loop"
return
else
echo continue
fi
}
for (( k=1; k<=3; k++ ))
do
myfunc
echo hello
done
Please help.

Your loop is all wrong and I don't know why you have an if / else if you're just interested in one output:
#!/usr/bin/env bash
myfunc() {
if [[ $k -lt 2 ]]; then
echo "hello my value is $k"
fi
}
for (( k=1; k<=3; k++ ))
do
myfunc
echo "$k just to prove it is looping" # this is always run regardless of what's in the function
done
output:
hello my value is 1
1 just to prove it is looping
2 just to prove it is looping
3 just to prove it is looping

#!/usr/bin/env bash
myfunc() {
if [[ $k -gt 1 ]]; then
echo "in the loop"
x=1
else
echo Welcome
fi
}
for (( k=1; k<=3; k++ ))
do
myfunc
if [[ $x -eq 1 ]];then
continue
fi
echo hello
done

Related

Error getting in the second if statement in bash script

n=20
x=3
count=0
flag=0
i=1
declare -a arr[n+1]
for (( j=0;j<=n;j++ ))
do
arr+=(0)
done
#echo "${arr[#]}"
while [[ $count -ne $n ]]
do
if [[ $i -le $n ]]
then
if [[ ${arr[$i]} -eq '0' ]]
then
echo "Value is ${arr[$i]}"
#${arr[$(i-1)]}= (( ${arr[$i-1]++} ))
${arr[$i]}+=${arr[$i]}
echo " "
#echo -n "${arr[$i]}"
echo -n " $i"
count=$(( count+1 ))
i=$(( i+1+x ))
else
i=$(( i+1 ))
fi
else
i=$(( i-n ))
flag=$(( flag+1 ))
fi
done
echo " "
echo "No of round : $flag"
This is the whole code, I've tried to print numbers that follows this: n=20 is the number of elements and x=3 is the number that we have to avoid. For example,
20
3
1,5,9,13,17,2,6,10,14,18,3,7,11,15,19,4,8,12,16,20,
3
But, the problem is that my second if condition is not fulfilling, if ignores the condition. Above example is for the C++, but in bash script, 2nd if statement isn't working. This can be because syntax is wrong. So can you please help me to find the mistakes.
Output of the above code:
output
${arr[$i]}+=${arr[$i]}
This is incorrect. $ should not be used when you assign the value.
If you want to double the value, replace this string with the following:
arr[$i]=$(( ${arr[$i]} + ${arr[$i]} ))
Or what you want to do there?

Difference between continue and colon in conditional statement

What is the difference between using a colon, which means "do nothing" and continue, which means skip.
if [[ -s $file ]] ; then
:
fi
if [[ -s $file ]] ; then
continue
fi
: is a synonym for true. It does not prevent later commands in the same block or loop from running.
Compare:
for (( i=0; i<3; i++ )); do
echo "Starting iteration $i"
(( i == 1 )) && { echo " About to run :"; :; echo " Just ran :"; }
(( i == 2 )) && { echo " About to run continue"; continue; echo " Just ran continue"; }
echo "Ending iteration $i"
done
Our output is:
Starting iteration 0
Ending iteration 0
Starting iteration 1
About to run :
Just ran :
Ending iteration 1
Starting iteration 2
About to run continue
Note that we made it to "ending" after running :, but not after running continue.
It depends on your program's logic.
Outside of a loop you get
$ continue
bash: continue: only meaningful in a `for', `while', or `until' loop

Shell script to output the largest

How to write a script which will receive a list of parameters and output the number that is the largest. If no parameters are supplied, output an error message.
I wrote the following code to check if no parameters are supplied, output an error message.
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "No arugments supplied"
else
echo "$# Parameter"
But I dont know how to continue...
Keep a current max. Loop over the input, updating max if necessary. At the end you'll have the global maximum.
Untested:
#!/usr/bin/bash
if [ $# -eq 0 ]; then
echo "Usage: $0 NUMBERS" >&2
exit 1;
fi
max="$1"
shift
while [ $# -gt 0 ]; do
if [ "$1" -gt "$max" ]; then
max="$1"
fi
shift
done
echo "$max"
Use sort -n (numeric) and -r (reverse) and then just pick the first line of the output -- like
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "No arugments supplied"
else
echo "$# Parameter"
for i in $*; do echo ${i}; done | sort -nr | head -1
fi
Now the only problem you are facing is when the the input (the arguments) are not numbers -- but you didn't say anything about what should happen then.
Here's a pseudocode you could implement:
save the first param in a variable called max
loop over the params
if the param is greater than max, update max
print max
Here's an example loop that prints all parameters:
for num; do
echo $num
done
And here's an example of comparing values:
if (( num > max )); then
echo $num is greater than $max
fi
This should be more than enough help to complete your homework.
Well since others have already gave you the actual solution, here's mine too:
#!/bin/bash
if (( $# == 0 )); then
echo "No arugments supplied"
exit 1
fi
max=$1
for num; do
if (( num > max )); then
max=$num
fi
done
echo $max

How can i loop my bash if statment until it meets the requirement

The code works if you do bash launch_script.sh 5 6 but if i do bash launch_script.sh 6 5 it asks for new start value but it doesn't use it in the script - the script just ends.
#!/bin/bash
a=$1
b=$2
if [ $1 -gt $2 ]
then
echo "$1 is bigger then $2, plz input new start number"
read -p "You're start number will be?: "
else
until [ $a -gt $b ];
do
echo $a
((a++))
done
fi
The loop is not executed, because it's part of the else block. If you want to run the loop always, put it after the end of the if:
#!/bin/bash
a=$1
b=$2
if (( $1 > $2 )) ; then
echo "$1 is bigger then $2, plz input new start number"
read -p "You're start number will be?: " a
fi
until (( $a > $b )) ; do
echo $((a++))
done
To loop over the read statement, just introduce a similar loop:
#!/bin/bash
a=$1
b=$2
while (( $a > $b )) ; do
echo "$1 is bigger then $2, plz input new start number"
read -p "You're start number will be?: " a
done
until (( $a > $b )) ; do
echo $((a++))
done
Note that I fixed several issues in your code:
read can assign the value directly to a variable.
Code should be indented for readability.
I also used the (( arithmetic condition )) syntax which is easier to understand, and included the increment to the echo.

Counting down in a loop to zero by the number being given

I am trying to write a while loop to determine the number is being given to count down to 0. Also, if there's no argument given, must display "no parameters given.
Now I have it counting down but the last number is not being 0 and as it is counting down it starts with the number 1. I mush use a while loop.
My NEW SCRIPT.
if [ $# -eq "0" ] ;then
echo "No paramters given"
else
echo $#
fi
COUNT=$1
while [ $COUNT -gt 0 ] ;do
echo $COUNT
let COUNT=COUNT-1
done
echo Finished!
This is what outputs for me.
sh countdown.sh 5
1
5
4
3
2
1
Finished!
I need it to reach to 0
#Slizzered has already spotted your problem in a comment:
You need operator -ge (greater than or equal) rather than -gt (greater than) in order to count down to 0.
As for why 1 is printed first: that's simply due to the echo $# statement before the while loop.
If you're using bash, you could also consider simplifying your code with this idiomatic reformulation:
#!/usr/bin/env bash
# Count is passed as the 1st argument.
# Abort with error message, if not given.
count=${1?No parameters given}
# Count down to 0 using a C-style arithmetic expression inside `((...))`.
# Note: Increment the count first so as to simplify the `while` loop.
(( ++count ))
while (( --count >= 0 )); do
echo $count
done
echo 'Finished!'
${1?No parameters given} is an instance of shell parameter expansion
bash shell arithmetic is documented here.
You should also validate the variable before using it in an arithmetic context. Otherwise, a user can construct an argument that will cause the script to run in an infinite loop or hit the recursion limit and segfault.
Also, don't use uppercase variable names since you risk overriding special shell variables and environment variables. And don't use [ in bash; prefer the superior [[ and (( constructs.
#!/usr/bin/env bash
shopt -s extglob # enables extended globs
if (( $# != 1 )); then
printf >&2 'Missing argument\n'
exit 1
elif [[ $1 != +([0-9]) ]]; then
printf >&2 'Not an acceptable number\n'
exit 2
fi
for (( i = $1; i >= 0; i-- )); do
printf '%d\n' "$i"
done
# or if you insist on using while
#i=$1
#while (( i >= 0 )); do
# printf '%d\n' "$((i--))"
#done
Your code is far from being able to run. So, I don't know where to start to explain. Let's take this small script:
#!/bin/sh
die() {
echo $1 >&2
exit 1;
}
test -z "$1" && die "no parameters given"
for i in $(seq $1 -1 0); do
echo "$i"
done
The main part is the routine seq which does what you need: counting from start value to end value (with increment in between). The start value is $1, the parameter to our script, the increment is -1.
The test line tests whether there is a parameter on the command line - if not, the script ends via the subroutine die.
Hth.
There are a number of ways to do this, but the general approach is to loop from the number given to an ending number decrementing the loop count with each iteration. A C-style for loop works as well as anything. You will adjust the sleep value to get the timing you like. You should also validate the required number and type of input your script takes. One such approach would be:
#!/bin/bash
[ -n "$1" ] || {
printf " error: insufficient input. usage: %s number (for countdown)\n" "${0//*\//}"
exit 1
}
[ "$1" -eq "$1" >/dev/null 2>&1 ] || {
printf " error: invalid input. number '%s' is not an integer\n" "$1"
exit 1
}
declare -i cnt=$(($1))
printf "\nLaunch will occur in:\n\n"
for ((i = cnt; i > 0; i--)); do
printf " %2s\n" "$i"
sleep .5
done
printf "\nFinished -- blastoff!\n\n"
exit 0
Output
$ bash ./scr/tmp/stack/countdown.sh 10
Launch will occur in:
10
9
8
7
6
5
4
3
2
1
Finished -- blastoff!
Your Approach
Your approach is fine, but you need to use the value of COUNT $COUNT in your expression. You also should declare -i COUNT=$1 to tell the shell to treat it as an integer:
#!/bin/bash
if [ $# -eq "0" ] ;then
echo "No paramters given"
else
echo -e "\nNumber of arguments: $#\n\n"
fi
declare -i COUNT=$1
while [ $COUNT -gt 0 ] ;do
echo $COUNT
let COUNT=$COUNT-1
done
echo -e "\nFinished!\n"

Resources