What does if [ $# -lt 2 ] mean?

I'm new to Unix/Linux. I'm trying to understand the code of the developer before me. Can someone please tell me what does this line if [ $# -lt 2 ] mean?


Solution 1:

In Bash $# expands to the number of positional parameters that have been set.

if [ $a -lt $b ] means if the value of a is less than the value of b.

if [ $# -lt 2 ] means if the number of positional parameters set is less than 2.

In a working example you would perhaps use this to count the parameters given to a function. If you define a function as:

count_words(){
  if [ $# -lt 2 ]
  then
    echo "There are less than two words."
  else
    echo "There are 2 or more words."
  fi
}

Then call the function with differing numbers of words, the results would be as follows:

$ count_words hello
There are less than two words.

$ count_words how many words
There are two or more words.

$ count_words
There are less than two words.

$ count_words two words
There are two or more words.

Solution 2:

This is a composition of three things:

  • $# is a shell variable which contains the number of positional arguments to a script or function.

  • [ is not special syntax, but rather the name of a program—it’s an alias for test. (Check out man [ or man test.)

    The command line of [ is parsed as an expression: [ $# -lt 2 ] is calling [ with the arguments $#, -lt, 2, and ] (which is just a visual delimiter). It returns a successful exit code, setting $? to 0 if the expression evaluates to true (i.e., if the number of arguments to the script is less than 2) or a failed exit code otherwise, setting $? to 1. You can see this by entering:

    [ 1 -lt 2 ]; echo $?    # 1 < 2 is true: 0
    [ 2 -lt 1 ]; echo $?    # 2 < 1 is false: 1
    
  • if condition; then body; fi evaluates the command condition, and, if it returns a successful exit code, proceeds to evaluate the commands in body.

It’s worth noting some things you may encounter:

  • The true utility always returns a successful exit code, and false always returns failure, so you can use them in conditions, e.g.:

    while true; do
      …
    done
    
  • if [ $foo = "yes" ] won’t work if $foo expands to the empty string ([ = yes ]), or to a string containing spaces ([ no thanks = yes ]). Therefore you’ll often see:

    if [ "x$foo" = "xyes" ]
    

    So that [ receives a single argument xno thanks as the first operand of =.

  • [[]] is a shell keyword (not a builtin), with special parsing rules to address the limitation above, and which may provide additional features.