-1

Discovered an oddity in a bash shell script that I do not understand. In the following code sequence, two strings are defined; one with a length of 99 characters, one with a length of 100 characters. The length of each of the strings is compared to the value 3. If the "<" operator is used, the test fails if the value of the first symbolic operand is greater than 99 (2 digits). If the "-lt" operator is used, the test works correctly for values greater than 99.

I have two questions: 1) Why? 2) Is this a bug or a feature?

#/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

The output of this test sequence is:

-- 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

Jim
  • 23
  • 4

1 Answers1

1

That's because -lt (but also -gt, -ne, -eg, etc) are used for numeric comparisment. The other compares strings lexicographically.

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

I can show it by using [ instead of [[:

$ [ "abc" -lt 0 ] || echo nope
bash: [: abc: integer expression expected
nope
Bayou
  • 3,293
  • 1
  • 9
  • 22