我没有受过 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
”是否不意味着 true?
任何对此的见解都将不胜感激,我很难过!
最佳答案
助记符如-lt
可以说来自原始 Fortran 比较器,例如 .LT.
从 20 世纪 50 年代后期开始。
是的,在 shell 中,-lt
进行“小于”数值比较。 (不过请注意,在 Perl 中,数字比较是 <
等,字符串比较由字母运算符表示,例如 -lt
!)
然而,在某些(也许是很多)shell 中,转换和比较很可能以本地长整型格式完成。如果您使用的是 32 位计算机,则您引用的值超出 32 位(有符号)范围 10 倍左右。在 64 位机器上,或使用 long long
的 shell ,你会没事的。
十进制数的十六进制等效值是 021715402012 = 0x50E56BD1C 和 021815402012 = 0x5144C9E1C;由于 8,它们不能是八进制的。(但是,如果 shell 确实将前导零解释为“八进制”,则第二个数字只是 021 或十进制的 17,因为 8 结束了八进制数。但是,64-我在(Mac OS X 10.7.3 和 RHEL 5)上测试的 bit shell 似乎都将它们视为十进制,而不是八进制。)
下面的示例代码在 64 位下编译后给出以下输出:
021715402012 = 240565532 = 0x050E56BD1C
021815402012 = 340565532 = 0x05144C9E1C
在 32 位下编译,输出如下:
021715402012 = 2147483647 = 0x007FFFFFFF
021815402012 = 2147483647 = 0x007FFFFFFF
如果这是在您的 shell 中发生的情况,那么 -lt
的结果行为将被解释。您可以通过测试这两个值是否为 -eq
来确认。 ;与直觉相反,假设您使用的是将其算法限制为 long
的 32 位 shell,这可能会评估为真。 (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;
}
关于linux - Shell:如果 a 小于 b, "a -lt b"是否不表示为真?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9345674/