bash 'if' тестът е неуспешен със стойност, по-голяма от 99 (2 цифри)

Открих странност в bash shell скрипт, която не разбирам. В следната кодова последователност са дефинирани два низа; един с дължина 99 знака, един с дължина 100 знака. Дължината на всеки от низовете се сравнява със стойност 3. Ако се използва операторът "‹", тестът е неуспешен, ако стойността на първия символен операнд е по-голяма от 99 (2 цифри). Ако се използва операторът "-lt", тестът работи правилно за стойности, по-големи от 99.

Имам два въпроса: 1) Защо? 2) Това грешка ли е или функция?

#/bin/bash

string99="abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrstuvwxy"
string100="abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrstuvwxyz"
lng99=`expr length $string99`
lng100=`expr length $string100`

echo 
echo "-- 99 --------- if [[ \$lng < 3 ]] -----------------"

  if [[ $lng99 < 3 ]]
  then
    echo "$string99 is $lng99 characters long."
  else
    echo "length of string is greater than 3"
  fi

echo 
echo "-- 99 -------- if [[ \$lng -lt 3 ]] ----------------"
  if [[ $lng99 -lt 3 ]]
  then
    echo "$string99 is $lng99 characters long."
  else
     echo "length of string is greater than 3"
  fi

echo 
echo "-- 100 -------- if [[ \$lng < 3 ]] -----------------"

  if [[ $lng100 < 3 ]]
  then
    echo "$string100 is $lng100 characters long."
  else
    echo "length of string is greater than 3"
  fi

echo 
echo "-- 100 ------- if [[ \$lng -lt 3 ]] ----------------"
  if [[ $lng100 -lt 3 ]]
  then
    echo "$string100 is $lng100 characters long."
  else
     echo "length of string is greater than 3"
  fi

Резултатът от тази тестова последователност е:

-- 99 --------- if [[ $lng < 3 ]] -----------------
length of string is greater than 3

-- 99 -------- if [[ $lng -lt 3 ]] ----------------
length of string is greater than 3

-- 100 -------- if [[ $lng < 3 ]] -----------------
abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890abcdefghijklmnopqrstuvwxyz is 100 characters long.

-- 100 ------- if [[ $lng -lt 3 ]] ----------------
length of string is greater than 3


person Jim    schedule 19.03.2020    source източник
comment
Не използвайте обратни отметки `. Използвайте $(...) вместо това. Не използвайте expr. Само lng99=${#string99}.   -  person KamilCuk    schedule 19.03.2020


Отговори (1)


Това е така, защото -lt (но също -gt, -ne, -eg и т.н.) се използват за цифрово сравнение. Другият сравнява низове лексикографски.

$ [[ "abc" < "bcd" ]] || echo "nope"
$ [[ "cbc" < "bcd" ]] || echo "nope"
nope
$ [[ "abc" -lt "bcd" ]] || echo "nope"
nope
$ [[ "cbc" -lt "bcd" ]] || echo "nope"
nope

Мога да го покажа, като използвам [ вместо [[:

$ [ "abc" -lt 0 ] || echo nope
bash: [: abc: integer expression expected
nope
person Bayou    schedule 19.03.2020
comment
Благодаря ти. Виждам, че това е функция, а не грешка. Умът ми беше заседнал в режим на цели числа. - person Jim; 20.03.2020