为什么

为什么

我正在编写一个 bash 脚本,突然出现这种行为:

[[ 1 < 2 ]]; echo $?  # outputs 0
[[ 2 < 13 ]]; echo $? # outputs 1

-lt运行良好:

[[ 1 -lt 2 ]]; echo $?  # outputs 0
[[ 2 -lt 13 ]]; echo $? # outputs 0

我是否不小心以<某种方式覆盖了?

这是我为测试此行为而编写的脚本:

#!/bin/bash

for a in {1..5}
do
    for b in {1..20}
    do
        [[ $a < $b ]] && echo $a $b
    done

    echo
done

这是输出:

1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
1 11
1 12
1 13
1 14
1 15
1 16
1 17
1 18
1 19
1 20

2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 20

3 4
3 5
3 6
3 7
3 8
3 9

4 5
4 6
4 7
4 8
4 9

5 6
5 7
5 8
5 9

在脚本中更改<为会给出正常输出(例如显示)。-lt5 10

重新启动并没有改变任何东西。

我的 bash 版本是 GNU bash,版本 4.3.42(1)-release (x86_64-pc-linux-gnu)。我使用的是 Ubuntu 15.10。我不知道这里还有哪些相关信息。

答案1

bash手册页。

当与 一起使用时[[<>运算符使用当前区域设置按字典顺序排序。

从输出来看,它似乎按设计工作。

在 bash 中使用:

  • [[ $a < $b ]]根据当前语言环境进行词典比较(使用strcoll(3)
  • [ "$a" -lt "$b" ]用于十进制整数比较。
  • (( a < b ))[[ $a -lt $b ]]用于算术表达式比较。请注意,当存储在其中$a并正在计算算术表达式时$b,这可能会产生副作用,包括运行任意命令。例如,x=5 a='++x' bash -c '[[ $a -lt $a ]]; echo "$? $x"'输出0 7a='x[$(reboot)]' b=a bash -c '[[ $a -lt $b ]]'重新启动系统(两次)。另请注意,对于这些,以 0 开头的数字被解释为八进制,而不是十进制。

答案2

怎么样:

for a in {1..5}; 
do     
  for b in {1..20};     
  do         
    (( $a < $b )) && echo $a $b
  done      
  echo
done

根据http://www.tldp.org/LDP/abs/html/dblparens.html

与 let 命令类似,(( ... )) 结构允许算术扩展和求值。在最简单的形式中,a=$(( 5 + 3 )) 会将 a 设置为 5 + 3 或 8。但是,这种双括号构造也是允许在 Bash 中对变量进行 C 风格操作的机制,例如, (( var++ ))。

答案3

首先,[[ 不是 POSIX应该避免。

其次,如果您希望用作<算术测试的一部分,您可以这样做,但使用不同的语法:

if [ "$((2 < 13))" -ne 0 ]
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi

或者:

if expr 2 '<' 13
then
  echo '2 is less than 13'
else
  echo '2 is greater or equal to 13'
fi

相关内容