#!/usr/bin/env bash
echo 'Using conditional expression:'
[[ ' ' < '0' ]] && echo ok || echo not ok
[[ ' a' < '0a' ]] && echo ok || echo not ok
echo 'Using test:'
[ ' ' \< '0' ] && echo ok || echo not ok
[ ' a' \< '0a' ] && echo ok || echo not ok
输出结果为:
Using conditional expression:
ok
not ok
Using test:
ok
ok
bash --version
:GNU bash, version 4.2.45(1)-release (x86_64-pc-linux-gnu)
uname -a
:Linux linuxmint 3.8.0-19-generic
答案 0 :(得分:5)
Bash手册说:
与[[,&lt;和&gt;运算符使用当前语言环境按字典顺序排序。测试命令使用ASCII排序进行排序。
这归结为分别使用strcoll(3)或strcmp(3)。
使用以下程序(strcoll_strcmp.c)对此进行测试:
#include <stdio.h>
#include <string.h>
#include <locale.h>
int main(int argc, char **argv)
{
setlocale(LC_ALL, "");
if (argc != 3) {
fprintf(stderr, "Usage: %s str1 str2\n", argv[0]);
return 1;
}
printf("strcoll('%s', '%s'): %d\n",
argv[1], argv[2], strcoll(argv[1], argv[2]));
printf("strcmp('%s', '%s'): %d\n",
argv[1], argv[2], strcmp(argv[1], argv[2]));
return 0;
}
注意区别:
$ LC_ALL=C ./strcoll_strcmp ' a' '0a'
strcoll(' a', '0a'): -16
strcmp(' a', '0a'): -16
$ LC_ALL=en_US.UTF-8 ./strcoll_strcmp ' a' '0a'
strcoll(' a', '0a'): 10
strcmp(' a', '0a'): -16
究竟为什么这些比较如此我不确定。这必须归功于一些英语词典排序规则。我认为确切的规则在ISO 14651 Method for comparing character strings and description of the common template tailorable ordering和随附的模板表中有所描述。 Glibc在libc/localedata/locales
下的源代码树中包含此数据。
答案 1 :(得分:4)
您正在观察的行为可以通过以下manual:
解释bash-4.1 and later use the current locale’s collation sequence and strcoll(3).
您似乎正在寻找基于ASCII排序规则的比较。您可以通过设置compat32
或compat40
来更改行为。
$ cat test
shopt -s compat40
echo 'Using conditional expression:'
[[ ' ' < '0' ]] && echo ok || echo not ok
[[ ' a' < '0a' ]] && echo ok || echo not ok
echo 'Using test:'
[ ' ' \< '0' ] && echo ok || echo not ok
[ ' a' \< '0a' ] && echo ok || echo not ok
$ bash test
Using conditional expression:
ok
ok
Using test:
ok
ok
从手册:
compat32
If set, Bash changes its behavior to that of version 3.2 with respect to locale-specific string comparison when using the ‘[[’ conditional command’s ‘<’ and ‘>’ operators. Bash versions prior to bash-4.0 use ASCII collation and strcmp(3); bash-4.1 and later use the current locale’s collation sequence and strcoll(3).
compat40
If set, Bash changes its behavior to that of version 4.0 with respect to locale-specific string comparison when using the ‘[[’ conditional command’s ‘<’ and ‘>’ operators (see previous item) and the effect of interrupting a command list.
答案 2 :(得分:2)
<
运算符在[ ]
或[[ ]]
内使用时,会根据ASCII字母顺序比较两个字符串。这意味着a
小于b
。这里需要注意的是,因为[ ]
有点困难和晦涩,你需要逃避<
,其他明智的基础认为你想要重定向。
然而,这两项测试是等价的:
[ 'a' \< 'b' ] && echo ok
[[ 'a' < 'b' ]] && echo ok
在您的示例中,' a'
肯定小于'0a'
,因为空格的小数值为20,而“0”的值为48。
所以我认为你在那里发现了一个错误。
[ ' a' \< '0a' ]
和
[[ ' a' < '0a' ]]
应该是等效的,[ ]
中的那个是正确的。