What does "while test $# -gt 0" do?

26,374

Solution 1

While # on it's own is definitely a comment, $# contains the number of parameters passed to your function.

test is an program which lets you perform various tests, for example, if one number is greater than another number (if your operator is -gt; there are many other operators, see man test). It will return success if the the test is successful (in this case, if the number of parameters IS greater than 0).

the shift command throws away the first parameter. It also decreases $#

The code as a whole can be seen as: do something with a parameter (in this case, showing it on the screen), then discard it; repeat until there are no parameters left.

If you want to see all the parameters that are left, useful for debugging, check the contents of $@

Solution 2

$# ==> script parameters passed

test ==> condition evaluation command

-gt ==> represents greater than

test a -gt b ==> true if a is greater than b, false otherwise

Putting it all together:

while test $# -gt 0 ==> while there are more parameters passed (the reason why this is changing is because of shift)

What make things tricky is shift within the body of the while loop.

$1 ==> represents always the first parameter

To make this more concrete, let's say you are passing parameters a, b and c.

$1 ==> represents a as this is your first parameter

by calling now shift, a is gone and your parameter list is now b and c therefore if you invoke $1 now it's b since this is now the first parameter in the list. Invoking shift once more your parameter list is now just c, therefore $1 is now c. Calling shift one more time leaves the parameter list empty therefore the while condition will not success (as the parameter list if not greater than 0 anymore as it's now zero in size) which will cause the while loop to terminate.

What are the gains of using shift and referring to the current parameter as $1?

It gives you the flexibility not to know in advance in your script how many parameters are passed in the script and regardless of that to iterate through them one by one referring within the while loop to the current param always as $1 since that means the head of the parameter list. By shifting eventually the parameter list will be empty therefore it's important to have the while condition to check whether it's greater than zero in order to terminate and not infinitely loop.

Solution 3

Run the below script to understand what the variables mean. Save the script as somescript.sh and call the script with some input parameters.

#!/bin/bash
echo "I display the total parameters passed to this script from commandline"
echo $#
echo "I display all the parameter values"
echo "Input: $@"
echo "I display the first parameter value"
echo "$1"

shift 
echo "After shift: $@"
Share:
26,374

Related videos on Youtube

TCZ8
Author by

TCZ8

Updated on September 18, 2022

Comments

  • TCZ8
    TCZ8 almost 2 years

    I'm trying to create a function and believe I found a good working example but I don't understand all the logic behind it.

    More specifically, on the "while" line, could someone explain what test is and does? what is $# (isn't # a comment char?) and were does the -gt 0 parameter comes from? couldn't find it in the while man page.

    Here is the example:

    function my_function()
    {
    while test $# -gt 0
    do
        $
    echo "$1"
        shift
    done
    }
    

    Thank you.

    • TCZ8
      TCZ8 about 10 years
      Thank you everyone for the answers. They were all very useful.
  • jasonleonhard
    jasonleonhard over 7 years
    I would also like to add this excellent reference