sections in this module City College of San Francisco - CS160B
Unix/Linux Shell Scripting
Module: Arguments
module list

Arguments

The book gives a reasonable description of arguments. This section adds a bit more information that is useful in writing scripts.

The first argument $0

The first argument contains the name of or path to the command. This argument is part of the positional parameters, although it is not counted in $#, included in the contents of $*, or affected by shift.

Our shell scripts find $0 useful when printing error messages. If our goal is to be Unix-like, we would like to generate error messages in a Unix fashion. Most Unix commands output their name as part of any error messages they produce:

$ grep xxx yyy
grep: yyy: No such file or directory
$ cat yyy
cat: yyy: No such file or directory

We can do that by referring to $0. If our shell script myss generates an error message like this:

echo "$0: cannot find file '$file'"

the message that comes out will contain the name of the shell script as well:

myss: cannot file file 'foo'

Unfortunately, the exact contents of $0 will vary a bit depending on how the shell script is invoked. If it is invoked with a path, $0 will contain the path. If it is invoked using your $PATH variable, $0 may contain an absolute path. We all agree that cat's error messages would look a bit strange like this:

$ cat yyy
/bin/cat: yyy: No such file or directory

Thus, it is customary to strip off the (possible) path component from $0 before any error messages are printed. You can do this using basename:

basename and dirname

basename and dirname operate on paths. Given a path they divide it into a directory part and the final segment, which is often a filename, called the base. In the path /pub/cs/gboyd/cs160b/class, the directory part would be /pub/cs/gboyd/cs160b  and the base would be class

Given a path in $p, dirname "$p" outputs the directory part of $p, and basename "$p" outputs the base part of $p

$pdirname "$p"basename "$p"
/pub/cs/gboyd/cs160b/class/pub/cs/gboyd/cs160bclass
class.class
cs160b/mysscs160bmyss

You can now use basename to extract the name of our shell script from $0 and output our message:

echo "$(basename "$0"): cannot find file '$file'"

or, if you have several messages to output, simply set a variable to your program's name for later use:

progname=$(basename "$0")

echo "$progname: cannot find file '$file'"

Remember, $0 is not altered by shift, counted in $#, nor a part of $*. It is constant thoughout your program. It is not even reset using set -- , which is described below.

Resetting your positional parameters

You cannot assign to a positional parameter directly. I hope you would agree that an attempt to do so looks very strange indeed:

1=hello

This attempt to assign to $1 is illegal.

You can, however, reset all of your positional parameters to new values at once, as if your shell script had been executed with a different set of commandline arguments. You can do this with a variation of the set command using the option -- (that's two dashes)

set -- my commandline arguments

This sets your positional parameters as follows

$ set -- my commandline arguments
$ echo $1
my
$ echo $2
commandline
$ echo $3
arguments
$ echo $#
3
$ echo $*
my commandline arguments
$

You can use the set -- command with command substitution to divide standard output of a command into words, assigning each to a positional parameter

$ wc -l who.out
4 who.out
$ set -- $(wc -l who.out)
$ echo $1
4
$ echo $2
who.out
$

Copy your arguments

Referring to $1 inside your program can make it hard to follow. It is much better to copy the positional parameters to named variables once you have examined them. We will learn how to examine variables in the next sections on if statements.


Prev This page was made entirely with free software on Linux:  
Kompozer
and LibreOffice    
Next

Copyright 2016 Greg Boyd - All Rights Reserved.

Document made with Kompozer