What's the difference between these:
SEC=$(mysql -hxxx -Pxxx -uxxx -pxxx -se "SELECT Seconds FROM tablename")
SEC=100
Both return the same result (100). But when I test it with:
if [ ${SEC} > 1 ]
then
echo "SEC GT 1"
else
echo "SEC LT 1"
fi
The first one returns:
"SEC GT 1"
The second one returns:
"SEC LT 1"
If however, I change it to:
if [ ${SEC} -gt 1 ]
then the result is reversed.
I'm assuming it's got something to do with the datatype, and that I presumbaly need to cast
one or the other to get the same result.
It's just that at present it's messing up my testing, as I have to remember to change the IF
section every time.
Best Answer
Originally,
[
was implemented as an ordinary command, identical totest
except that[
expects an extra argument at the end which must be]
. (It still exists as an ordinary command, but most shells also have those as built-ins.) Given that it's an ordinary command subject to ordinary parsing, it couldn't use mathematical operators<
and>
without quoting:[ ${SEC} > 1 ]
contains a redirection operator, it's equivalent to[ ${SEC} ] >1
, redirecting the (empty) output of the[
command to the file called1
. The[
command mostly follows the usual convention of making special options beginning with a dash: most of its operators begin with a dash. So there's[ -r foo ]
to test whether a file is readable,[ -r foo -a -w bar ]
to combine two tests with the “and” operator,[ $x -eq $y ]
to test whether$x
and$y
are equal, etc.These older shells had string equality (the
=
operator, one of the few that deviates from the dash-letter convention) but not string ordering¹. They had numerical comparisons though, e.g.[ $x -le $y ]
to test whether the integer$x
is smaller or equal to$y
, and this set of operators includes numerical equality[ $x -eq $y ]
where[ 010 -eq 8 ]
because a leading zero means that the number is in octal.Ksh introduced the syntax
[[ … ]]
, also available now in bash and zsh. Unlike[ … ]
, which is an ordinary command,[[ … ]]
is recognized by the shell's parser, and so special characters such as(
and<
can be used inside without quoting (and indeed they must not be quoted). Since-lt
and friends were already available for numerical comparisons, and=
was already doing a string comparison,<
and friends were made string comparison operators (lexicographic order¹). Thus, for example,[ 9 -lt 10 ]
but[[ 10 < 9 ]]
.¹ String ordering is available with the
expr
utility; it's one of the few uses ofexpr
that haven't been subsumed by features of POSIX shells. But beware thatexpr
uses the same operator for string and numerical comparisons, soexpr 9 \< 10
butexpr a9 \> a10
.² Whether the strings are interpreted as byte strings, or as character strings in the current locale, depends on the shell