What does "while test $# -gt 0" do?
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 shift
ing 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: $@"
Related videos on Youtube
TCZ8
Updated on September 18, 2022Comments
-
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 about 10 yearsThank you everyone for the answers. They were all very useful.
-
-
jasonleonhard over 7 yearsI would also like to add this excellent reference