I'm not trained in Linux, but I can muddle through with some doc lookups, but I'm stumped.
I found a script that helps set the date on my dd wrt router when it starts up, but only if the current date is less than the stored date. I can share the whole script if you want, but it boils down to this statement not evaluating to true when I expect it to. I'm putting the literals in, rather than the variables, and it still does not return true, it executes the "else" statement:
if [ 021715402012 -lt 021815402012 ]
then
echo "the first seems less than the second"
else
echo "the first does not seem less than the second for some reason"
fi
I would expect "the first seems less than the second" but this is not the case... Is it an overflow problem? I tried to make it a string compare like this:
if [ x021715402012 -lt x021815402012 ]
and tried putting it in quotes:
if [ "x021715402012" -lt "x021815402012" ]
it always executes the else. Does "a -lt b
" not mean true if a is less than b?
Any insight into this would be appreciated, I'm stumped!
The mnemonics such as -lt
might be said to come from the original Fortran comparators such as .LT.
from the late 1950s.
Yes, in the shell, -lt
does a 'less than' numeric comparison. (Be aware, though, that in Perl, the numeric comparisons are <
etc, and the string comparisons are denoted by the alphabetic operators such as -lt
!)
However, in some, perhaps many, shells the conversion and comparison may well be done in the local long integer format. If you're on a 32-bit machine, the values you quote exceed the 32-bit (signed) range by a factor of 10 or so. On a 64-bit machine, or with a shell that uses long long
, you'd be OK.
The hex equivalents of the decimal numbers are 021715402012 = 0x50E56BD1C and 021815402012 = 0x5144C9E1C; they can't be octal because of the 8. (However, if the shell does interpret the leading zero as 'octal', then the second number is just 021 or 17 decimal because the 8 ends the octal number. However, the 64-bit shells I tested on (Mac OS X 10.7.3 and RHEL 5) both seemed to treat them as decimal, not octal.)
The example code below, compiled under 64-bit gives the following output:
021715402012 = 240565532 = 0x050E56BD1C
021815402012 = 340565532 = 0x05144C9E1C
Compiled under 32-bit, it gives the following output:
021715402012 = 2147483647 = 0x007FFFFFFF
021815402012 = 2147483647 = 0x007FFFFFFF
If this was what happened in your shell, then the resulting behaviour of -lt
would be explained. You could confirm it by testing whether the two values are -eq
; counter-intuitively, this would probably evaluate to true under the hypothesis that you are using a 32-bit shell that limits its arithmetic to long
(32-bit) signed integers.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *array[] = { "021715402012", "021815402012" };
for (int i = 0; i < 2; i++)
{
int j = atoi(array[i]);
long k = strtol(array[i], 0, 10);
printf("%-10s = %10d = 0x%.10lX\n", array[i], j, k);
}
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With