This question already has answers here:
Is there a list of 'if' switches anywhere?
(5 answers)
Closed 26 days ago.
I don't understand the following shell operators function.
if [ $count -lt 2 ]
then
echo $CLASS $TC >> $WORKSPACE/testcasestoremove.txt
fi
what exactly -lt doing here?
and
if [ $linesToRemove -gt 0 ]
then
cat $WORKSPACE/testcasestoremove.txt
exit 1
fi
what exactly -gt is doing here?
I did some research but I can not found anything related to that. Any help will be much appreciated.
They are 'less than' and 'greater than' comparison operators.
From the bash manual (man bash):
arg1 OP arg2
OP is one of -eq, -ne, -lt, -le, -gt, or -ge. These arithmetic binary operators return true if arg1 is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to arg2, respectively. Arg1 and arg2 may be positive or negative integers.
Related
This question already has answers here:
How can I compare two floating point numbers in Bash?
(22 answers)
Closed 5 years ago.
I have a case like this:
string1="some_string"
string2="some_string"
int1="0.87"
int2="${var}"
$var is the output of some other script, and it has the form 0.994343123 or 0.3454657 or whatever (starts with 0. and the biggest value is around 0.9972343)
Now, I don't know how bash works, but usually string 0.87 is never less than or equal to 0.9999999, they are just different.
I would need something like this (pseudocode):
if (string1 equals string2 and int1 is less than int2):
do something;
else
do something else.
What i would expect is 0.87687 is greater than 0.87 (correct?? i was never good at math...)
Can anyone help me with the code for that if??
Thanks in advance!
Since bash does not handle floating point arithmetic, you may use bc -l to compare 2 floating point numbers and join the condition with && as:
if [[ $string1 = $string2 && $(bc -l <<< "$int1 < $int2") -eq 1 ]]; then
echo "yes"
else
echo "no"
fi
If the values are between 0 and 1, string comparison will work
s1=..; s2=..
v1="0.876"; v2="0.87"
[[ $s1 = $s2 && $v1 > $v2 ]] && echo yes || echo no
a=0.86
b=0.865
if ((`echo $a '<' $b|bc`)); then echo 'a<b'; fi
(You can replace the last line by
if (($(echo $a '<' $b|bc))); then echo 'a<b'; fi
but imho it is less readable)
This question already has answers here:
How can I compare two floating point numbers in Bash?
(22 answers)
Closed 6 years ago.
I am new to bash scripting. My code is :
MK=M
SM=1.4
if [[ $MK == "M" ]]
then
if [ $SM -gt 1.3 ]
then
echo "Greater than 1.3M"
else
echo "Less than 1.3M"
fi
else
echo "Not yet M...."
fi
Reply:
/tmp/tmp.sh: line 6: [: 1.4: integer expression expected
Less than 1.3M
What am i doing wrong ?
Here's what man bash says:
arg1 OP arg2 ... Arg1 and arg2 may be positive or negative integers.
You seem to be trying to compare floating point numbers.
It's ultimately because bash is not terribly patient when it comes to floating point numbers. In very simple terms here, I would suggest you do one of two things:
It looks like you are trying to determine if something is larger than 1.3 Mb or not, is this correct? If this is the case, then leave everything the way you have it, and just use Kb for $sm and the compare
like this:
#/bin/bash
mk="p"
km="p"
sm="1400"
ms="1300"
if [[ $mk == $km ]]
then
if [ $sm > $ms ]
then
echo "Greater than 1.3M"
else
echo "Less than 1.3M"
fi
else
echo "Not yet M...."
fi
or
Use bc for the calculation of the floating point numbers...
# /bin/bash
mk="p"
km="p"
sm="1.4"
ms="1.3"
if [ $(echo "$mk == $km" | bc) ]
then
if [ $(echo "$sm > $ms" | bc) ]
then
echo "Greater than 1.3M"
else
echo "Less than 1.3M"
fi
else
echo "Not yet M...."
fi
One more thing to note here, is that, as you can see from my code, I have primed new variables with the data, rather than using raw letters and numbers in boolean and compare operations, which can have some genuinely unexpected results. Also, while they may work in some conditions, temporarily, bash prefers all variable names to be in lower-case. Let me know if you have any questions.. However, I have tested both code chunks, and they both work fine.
This question already has answers here:
Arithmetic expressions in Bash?
(5 answers)
Closed 6 years ago.
I am doing a school assignment in bash and got this code:
if a < 0
a = a/b
else
a = b/a
fi
The assignment says that we need to divide two number read from the keyboard, and check if the first number is larger than the number 0.
echo "Write two numbers, with a space, that need to be divided:"
read a b
if a > 0
a = $a / $b
else
a = $b / $a
fi
echo "$a"
What am I doing wrong here?
Creating a math context in bash uses (( )). Note that bash only supports integer math natively -- be sure you aren't expecting fractional output (or using fractional inputs), and see BashFAQ #22 if this limitation is relevant to you.
if (( a > 0 )); then
a=$(( a / b ))
else
a=$(( b / a ))
fi
This question already has answers here:
Sequences expansion and variable in bash [duplicate]
(7 answers)
Closed 7 years ago.
Im trying a code in bash to generate prime nos as follows:
#!/bin/bash
echo "Enter till where u wish to generate"
read num
echo "Generating prime numbers from 2 to $num"
flag="prime"
for i in {2..$num}
do
for j in {2..$((${num}-1))}
do
[ $((${i}%${j})) -eq 0 ] && flag="nprime" || flag="prime"
break
done
[ "$flag" == "prime" ] && echo "$i"
done
Upon execution, it throws an error because the for loop takes the sequence mentioned in the curly braces as it is not as a sequence.
Could you guide me as to where am i going wrong ?
man bash in my version says:
A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters, and incr, an optional increment, is an integer.
You can't use variables in ranges. Try seq instead:
for i in $(seq 2 $num) ; do
Note that incr for seq goes between x and y.
Use:
for ((i=2; i<=$num; i++))
I can't help noticing there are so many shell codes using comparison operators as test command's arguments, not with signs.
For example, to test if no arguments are received in shell using test:
if test $# -eq 0
then
echo "No arguments received"
fi
Why can't we replace -eq with more, say, traditional, intuitive, familiar, universal, and, readable sign with ==? So that we have the following:
if test $# == 0
then
echo "No arguments received"
fi
The same goes with other comparison operators < <= => >.
I'm assuming there must be some technical reasons behind this (perhaps compatibility issue?) to favor -eq format over ==, but I'm not aware of them.
First of all, use $#, not $#.
The technical reason for the difference is that the operators define how the operands are interpretted.
For <, = and >, the operands are considered strings. This means that 10 < 2 because 1-something comes before 2-something in the alphabet, and 1 != 01 because the strings are of different lengths.
For -eq, -gt, -lt, the operands are considered integers. This means that 2 -lt 10 because the number 2 is smaller than the number 10, and 1 -eq 01 because these are both numerically equivalent ways of writing 1.
You can use (( and )) (arithmetic processor) in BASH that supports all the operators like ==, >=, <=, <, > etc:
if (( $# == 0 ))
then
echo "No arguments received"
fi
PS: # of parameters is represented by $#