Migrated to Almalinux 9 from CentOS 7 I've written a simplest Bash script to control quantity of inotifywait processes (must be 11) - but I was very surprised the results depending on compare operator used.
(BASH - GNU bash, version 5.1.8(1)-release (x86_64-redhat-linux-gnu))
#!/bin/bash
itf=$(ps aux | grep [i]notify | wc -l);
status=$(mysql -uroot -N -e 'SELECT status FROM db.table WHERE filename LIKE "rates.xml"');
echo "$itf"; # correct value - 11
echo "$status"; # correct value - OK
printf "First compare numeric\n"
if [[ "itf" -eq 11 ]] ; then
echo "OK - all 11 inotifywait processes run";
else
printf "Just $itf inotifywait processes running of 11\n";
fi
printf "Second compare string just experiment\n"
if [[ "$status" != "OK" ]]; then
echo STATUS BAD ;
else
echo STATUS GOOD ;
fi
exit ;
sh
I do not see any errors in coding above - but result for count is wrong. In spite of bash counted 11 processes (as should be) - it shows negative result
Just 11 inotifywait processes running of 11
But when I change compare operator from
if [[ "itf" = 11 ]] ; then
to
if [[ "itf" -eq 11 ]] ; then
then I have positive result as should be
OK - all 11 inotifywait processes run
At the same time it seems NO MATTER what operator to use when compare strings. I was tested both
if [[ "$status" != "OK" ]]; then
if [[ "$status" -ne "OK" ]]; then
both cases we have correct result
STATUS GOOD
No matter run script as SH or BASH.
My question is - should we ALWAYS use in bashes the "text" compare operators like "-ne", "-eq" etc - because they are UNIVERSAL for all kind of comparisons, string or numeric or whatever else ? Thx in advance for your opinions,
In Bash there are only strings.
-ne
-eq
compare numbers, or in the context of [[
, arithmetic expressions.
In arithmetic expression, string that is not a variable is replaced by 0
.
$ if [[ "OK" -eq 0 ]]; then echo true; fi
true
$ if [[ "literally_anything" -eq 0 ]]; then echo true; fi
true
$ if [[ "literally_anything" -eq "something_completely_else" ]]; then echo true; fi
true
$ literally_anything=1
$ something_completely_else=2
$ if [[ "literally_anything" -eq "something_completely_else" ]]; then echo true; else echo false; fi
false
if [[ "itf" -eq 11 ]] ; then
itf
is a variable. -eq
evaluates itf
and expands it.
You meant to write if [[ "$itf" = 11 ]] ; then
to compare strings in your code.
It might be more readable to if ((itf == 11))
.
if [[ "$status" -ne "OK" ]]; then
$status
expands to some text. This text happens not to be a variable. So it becomes 0
. OK
is also not a variable, so it becomes 0
.
What bash compare operator always works for string and numeric comparisons
None. =
compares strings. -ne
-eq
compare numbers.