我没有接受过Linux培训,但我可以通过一些文档查找来解决问题,但我很难过。
我找到了一个脚本,可以帮助我在dd wrt路由器启动时设置日期,但前提是当前日期小于存储日期。如果你愿意,我可以分享整个脚本,但是归结为这个声明在我预期的时候没有评估为真。我将文字放入,而不是变量,它仍然不返回true,它执行“else”语句:
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
我希望“第一个似乎不到第二个”,但事实并非如此...... 这是溢出问题吗?我试着把它变成这样的字符串比较:
if [ x021715402012 -lt x021815402012 ]
并尝试将其放在引号中:
if [ "x021715402012" -lt "x021815402012" ]
它总是执行else。如果a小于b,“a -lt b
”是不是真的?
任何对此的见解都会受到赞赏,我很难过!
答案 0 :(得分:3)
-lt
等助记符可以说是来自20世纪50年代后期.LT.
等原始Fortran比较器。
是的,在shell中,-lt
执行'小于'数字比较。 (请注意,在Perl中,数字比较为<
等,字符串比较由字母运算符表示,例如-lt
!)
然而,在一些(可能是很多)shell中,转换和比较可以用本地长整数格式完成。如果您使用的是32位计算机,则引用的值超过32位(带符号)范围10倍左右。在64位计算机上,或者使用long long
的shell,你会没事的。
十进制数的十六进制等值为021715402012 = 0x50E56BD1C和021815402012 = 0x5144C9E1C;因为8,它们不能是八进制的。(但是,如果shell确实将前导零解释为'八进制',那么第二个数字只是021或17十进制,因为8结束了八进制数。但是,64-我测试的位shell(Mac OS X 10.7.3和RHEL 5)似乎都将它们视为十进制,而不是八进制。)
下面的示例代码,在64位下编译,给出以下输出:
021715402012 = 240565532 = 0x050E56BD1C
021815402012 = 340565532 = 0x05144C9E1C
在32位下编译,它提供以下输出:
021715402012 = 2147483647 = 0x007FFFFFFF
021815402012 = 2147483647 = 0x007FFFFFFF
如果这是你的shell中发生的事情,那么将解释-lt
的结果行为。您可以通过测试这两个值是否为-eq
来确认;反直觉地说,在使用32位shell将其算术限制为long
(32位)有符号整数的假设下,这可能会评估为真。
#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;
}
答案 1 :(得分:1)
您使用的是什么外壳和版本?某处有嵌入式控制角色的机会吗? (尝试删除重新键入代码。)在openSUSE 11.2(x86_64)上:
$if [ 021715402012 -lt 021815402012 ]; then echo yes; else echo no; fi
yes
有趣的是,
$if [ 012 -lt 11 ]; then echo yes; else echo no; fi
no
这让我感到惊讶,因为man bash
表示-lt
执行算术比较,而带前导0的常量被解释为八进制。所以我希望这能测试10是否小于11,因为012 base 8 = 8 + 2。
有人可以让我们直截了当吗?
答案 2 :(得分:1)
正在发生一些事情......
您的shell似乎使用了32位算术,并且您的数字溢出了格式。
此外,shell脚本中的所有命令参数都是字符串,因此除非参数中的字符对shell解析器有意义,否则引号将完全没有效果。
shell if
语句实际上正在运行the test(1) command,它作为简写链接到[
。 (然后它忽略了最后的]
。)虽然命令可以使用相同的运算符进行数字和字符串比较,但是当命令设计时,运算符采用某种类型,{ {1}}假设为数字。
关于bash和ash(破折号)我在 x ... 示例中收到错误消息。
答案 3 :(得分:0)
我不确定你的特定shell是否正在使用这种解释,但这就是我认为正在发生的事情:
021715402012
是一个11位八进制数。 021815402012
是一个两位数的八进制数,以非八进制数字(8
)结尾。
021715402012
和021
,显然第二个更小。
关于您的其他尝试,test
和[
命令的文档表明-lt
仅对数字参数有效,而不是字符串。