loop control to break from current if loop - exit

I am trying loop control. while loop then a for loop and inside it there are couple of if loops, if 3 of the if loop satisfies it should exit the for loop to continue with while loop else it should exit the if loop to continue rest of for loop iterations
LIMIT=100
while [ "count" -le "$LIMIT" ]
do
for i in 1 2 3 4 5
do
var a
var b
var c
var d
if [ $d -eq 1 ] && [ $a == Done ] && [ $b -eq 0 ]
then
echo "$c" | tr '\n' '\t'
echo "Successful"
break 2 # Need to exit entire for loop
elif [ $d -eq 0 ] && [ $a == Done ] && [ $b -eq 0 ]
then
break # Need to go to next iteration of for
elif [ $a == Active ]
then
echo "Active" # Need to exit entire for loop
break 2
elif [ $d -eq 1 ] && [ $a == Done ] && [ $b -gt 0 ]
then
echo "Fail" # Need to exit entire for loop
break 2
elif [ $a == Queued ]
then
echo "Queued" # Need to exit entire for loop
break 2
else
echo "Nothing"
fi
done
done
For some reason it exits everything when first if loop is true.

Got it, actually I was using break 2 which was exiting for as well as while as if is already being exited so using single break would let me exit for loop entirely, and to continue for next iteration for any of the if loop needed to use continue.
so the code should be
LIMIT=100
while [ "count" -le "$LIMIT" ]
do
for i in 1 2 3 4 5
do
var a
var b
var c
var d
if [ $d -eq 1 ] && [ $a == Done ] && [ $b -eq 0 ]
then
echo "$c" | tr '\n' '\t'
echo "Successful"
break # will exit entire for loop
elif [ $d -eq 0 ] && [ $a == Done ] && [ $b -eq 0 ]
then
continue # will go to next iteration of for
elif [ $a == Active ]
then
echo "Active"
break # will exit entire for loop
elif [ $d -eq 1 ] && [ $a == Done ] && [ $b -gt 0 ]
then
echo "Fail"
break # will exit entire for loop
elif [ $a == Queued ]
then
echo "Queued"
break # will exit entire for loop
else
echo "Nothing"
fi
done
done

Related

smallest value issue in shell script

I'm trying to find most negative value that are stored in array.
I used the following code
small=99999.999
for M in ${val[#]}
do
if [ "$M" \< "$small" ]
then small="$M"
fi
done
Let's consider the values are
0
0.5764
1.2934
0.8826
3.3143
2.8783
4.5771
0.549
2.4977
0.2294
1.0407
-0.0854
0.1819
1.911
0.5448
1.1276
0.2128
1.5406
-0.2361
-0.7184
-0.0082
The above code is producing smallest value as -0.0082 which is not the answer.
Can anybody pl let me know the fact?
You are comparing strings (lexicographical order), instead you can put your condition in double parenthesis (to perform a numeric comparison) if((a < b)); then or use -lt notation:
#!/bin/bash
for M in ${val[#]}
do
if [ "$M" -lt "$small" ]
then small="$M"
fi
done
Try it out in bash:
if \[ 100 \< 2 \]; then echo "yes"; else echo "no"; fi
it will output yes, but its false.
if ((100 < 2)); then echo "yes"; else echo "no"; fi
it will output no, which is true.
if \[ 100 -lt 2 \]; then echo "yes"; else echo "no"; fi
it will also give you the correct answer.
But bash only handles integer math, so you can use bc in your condition:
if [ $(bc <<< "$M < $small") -eq 1 ]

Negative to positive number range in regex in bash scripting [duplicate]

I want to just insert number between two values, and otherwise the script repeated until correct number.
This is my script and it does not work correctly:
validation(){
read number
if [ $number -ge 2 && $number -ls 5 ]; then
echo "valid number"
break
else
echo "not valid number, try again"
fi
}
echo "insert number"
validation
echo "your number is" $number
If you are using Bash, you are better off using the arithmetic expression, ((...)) for readability and flexibility:
if ((number >= 2 && number <= 5)); then
# your code
fi
To read in a loop until a valid number is entered:
#!/bin/bash
while :; do
read -p "Enter a number between 2 and 5: " number
[[ $number =~ ^[0-9]+$ ]] || { echo "Enter a valid number"; continue; }
if ((number >= 2 && number <= 5)); then
echo "valid number"
break
else
echo "number out of range, try again"
fi
done
((number >= 2 && number <= 5)) can also be written as ((2 <= number <= 5)).
See also:
Test whether string is a valid integer
How to use double or single brackets, parentheses, curly braces
Your if statement:
if [ $number -ge 2 && $number -ls 5 ]; then
should be:
if [ "$number" -ge 2 ] && [ "$number" -le 5 ]; then
Changes made:
Quoting variables is considered good practice.
ls is not a valid comparison operator, use le.
Separate single-bracket conditional expressions with &&.
Also you need a shebang in the first line of your script: #!/usr/bin/env bash
if [ $number -ge 2 && $number -ls 5 ]; then
should be
if [[ $number -ge 2 && $number -le 5 ]]; then
see help [[ for details
Try bellow code
echo "Enter number"
read input
if [[ $input ]] && [ $input -eq $input 2>/dev/null ]
then
if ((input >= 1 && input <= 4)); then
echo "Access Granted..."
break
else
echo "Wrong code"
fi
else
echo "$input is not an integer or not defined"
fi
2 changes needed.
Suggested by Sergio.
if [ "$number" -ge 2 ] && [ "$number" -le 5 ]; then
There is no need of break. only meaningful in a for, while, or until loop
while :; do
read option
if [[ $option -ge 1 && $option -lt 4 ]]; then
echo "correct"
c
break
else
echo "Incorrect option selected,choose an option between [1-4]"
fi
done

Bash script - user inputs 2 digits seperated by a space; need to verify it's a digit

Need to have a read statement in BASH that will ask user to input 2 digits on the same line with a space in between. Check if both are digits and there is a space in between.
#!/bin/bash
while :
do
read -p "digits a b?: " resp
if [ -z "${resp}" ] ; then continue;fi
respCtrl=`echo $resp | sed 's/[^0-9 ]//g'`
if [ ! ${#respCtrl} -eq ${#resp} ] ; then continue ;fi
set ${resp}
digit1=$1
digit2=$2
if [ "${digit1} ${digit2}" != "${resp}" ] ; then continue;fi
echo ${digit1} ${digit2}
break
done
#!/bin/bash
result=""
while [[ $result == *" "* || $result == "" ]];do
read -p "Type 2 digits without space:" result;
echo "Error";
done

What's the error with this BASH regex script?

I'm trying to make a program that reads in n strings and checks them for pertaining to a regex pattern: XXXXX1234X where X is an uppercase character and {1,2,3,4} is any digit. As far as I checked, the regex pattern is correct. The problem seems to be in the input and comparison of strings.
read n
i=0
declare -a str
while [ $i -lt $n ]
do
read 'str[$i]'
i=$((i+1))
done
i=0
while [ $i -lt $n ]
do
[[ $(str[$i]) =~ ^([A-Z]){5}([0-9]){4}([A-Z]){1}$ ]] && echo YES || echo NO
i=$((i+1))
done
I did a minor modification to your code, I replaced the ( and ) with { } in the regex test:
[[ ${str[$i]} =~ ^...
Ran some test and it worked:
#!/bin/bash
read n
i=0
declare -a str
while [ $i -lt $n ]
do
read 'str[$i]'
i=$((i+1))
done
i=0
while [ $i -lt $n ]
do
[[ ${str[$i]} =~ ^([A-Z]){5}([0-9]){4}([A-Z]){1}$ ]] && echo YES || echo NO
i=$((i+1))
done

if statements in grub2 script always evaluate to true

I'm trying to write a grub2 bootloader script but if statements always evaluate to true:
if [ -s blabla ] ; then set zzz0="1" ; fi
if [ ! -s blabla ] ; then set zzz1="1" ; fi
set TEST_VAR=foo
if [ "x${TEST_VAR}" = "xfoo" ] ; then set zzz2="1" ; fi
if [ "x${TEST_VAR}" = "xbar" ] ; then set zzz3="1" ; fi
if [ $TEST_VAR = foo ] ; then set zzz4="1" ; fi
if [ $TEST_VAR = bar ] ; then set zzz5="1" ; fi
So, after running this script, I see all zzz (zzz0, zzz1, zzz2, zzz3, zzz4, zzz5)variables set to 1. What am I doing wrong?
Thanks,
Johnny
if [ ! "${myvar}" = "" ]; then
(lines here)
else
(lines here)
fi
if [ "${myvar}" = "fred" ]; then
(lines here)
else
(lines here)
fi