3. Positional parameters
-
The shell provides a set of variables called positional parameters that contain the individual words on the command line.
Let's test them with a simple script:
posit-param.sh
#!/bin/bash
# posit-param: script to view command line parameters
echo "
\$0 = $0
\$1 = $1
\$2 = $2
\$3 = $3
\$4 = $4
\$5 = $5
\$6 = $6
\$7 = $7
\$8 = $8
\$9 = $9
Number of arguments: $#
"vim posit-param.sh
./posit-param.sh
$(pwd)/posit-param.sh
Notice that
$0
contains th first word of the command, which is the name and path of the command itself../posit-param.sh a b c d
The special variable
$#
contains the number of arguments.If we need to use more than 9 arguments, then we can use
${10}
,${11}
etc. to access them (with curly braces). -
The
shift
command causes all the parameters to "move down one" each time it is executed.posit-param2.sh
#!/bin/bash
# posit-param2: script to display all arguments
count=1
while [[ $# -gt 0 ]]; do
echo "Argument $count = $1"
count=$((count + 1))
shift
donevim posit-param2.sh
In this example there is a loop that evaluates the number of arguments remaining and continues as long as there is at least one.
./posit-param2.sh a b c d
./posit-param2.sh a b c d e f g
-
Here is another example:
file-info.sh
#!/bin/bash
# file-info: simple file information program
PROGNAME="$(basename "$0")"
if [[ -e "$1" ]]; then
echo -e "\nFile Type:"
file "$1"
echo -e "\nFile Status:"
stat "$1"
else
echo "$PROGNAME: usage: $PROGNAME file" >&2
exit 1
fivim file-info.sh
This program displays the file type (determined by the
file
command) and the file status (from thestat
command) of a specified file.It checks the first argument, and if it does not exist, exits with an error message that shows how to use this script.
The command
basename
gets only the name of the file (discarding the path)../file-info.sh
./file-info.sh posit-param2.sh
./file-info.sh .
./file-info.sh xyz
-
Positional parameters can be used with functions as well.
file-info-fun.sh
#!/bin/bash
file_info () {
if [[ -e "$1" ]]; then
echo -e "\nFile Type:"
file "$1"
echo -e "\nFile Status:"
stat "$1"
else
local PROGNAME="$(basename "$0")"
echo "$PROGNAME: usage: $FUNCNAME file" >&2
return 1
fi
}
echo -e '\nCalling file_info without args: file_info'
file_info
FILE=$0
echo -e '\nCalling file_info with an argument: file_info $FILE'
file_info $FILEvim file-info-fun.sh
Notice that
$0
always contains the full pathname of the first item on the command line (i.e., the name of the program), even inside a function.Notice also that
FUNCNAME
is a variable that always contains the name of the current function../file-info-fun.sh
-
The shell provides two special variables that contain the list of all the positional parameters. They are
$*
and$@
. Let's try an example that shows their differences:posit-param3.sh
#!/bin/bash
# posit-params3: script to demonstrate $* and $@
print_params () {
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$3 = $3"
echo "\$4 = $4"
echo
}
pass_params () {
echo '-- $* --' ; print_params $*
echo '-- "$*" --' ; print_params "$*"
echo '-- $@ --' ; print_params $@
echo '-- "$@" --' ; print_params "$@"
}
pass_params "word" "words with spaces"vim posit-param3.sh
./posit-param3.sh
You see that both
$*
and$@
give 4 parameters."$*"
gives a single parameter, and"$@"
gives back the two original parameters. This happens because$*
is a string list of all the parameters, while$@
is an array of all the parameters.Anyway, the most useful construct seems to be
"$@"
because it preserves the original list of the parameters, and this is what we want in most of the cases.