|
|
![]() |
|
|
Processing Command-Line Arguments in Qshell Scripts by Ted Holt In my article "Working with Parameters and Variables in Qshell Scripts," I explained how to reference positional parameters in Qshell scripts. In this article, I cover the same subject in more depth. I cover the types of arguments that may be supplied to parameters and provide some effective ways for loading parameter values in Qshell scripts.
As in earlier articles, I use a variety of script fragments. For the sake of simplicity, I refer to each one of them as if the file name of the script is myscript.qsh. Types of Arguments Two terms you should understand are parameter and argument. Strictly speaking, an argument is a value that is passed to a script or program. A parameter is a variable defined in a program to represent the argument. It is common in iSeries and AS/400 computing to use the word parameter to mean both parameters and arguments. In this article I will try to use the words according to their strict meanings. Command-line arguments follow a command name. They are separated from the command name, and from one another, by white space. In the following example, three arguments are supplied to myscript.qsh. myscript.qsh -n -o mydata.dat Notice the two special arguments that begin with a hyphen (-). These are called options. Options are typically used to control the behavior of a script; whereas other parameters (should we call them non-options?) supply data values to the script. In script programming, the order in which the options are specified should be of no importance. The following command should be equivalent to the preceding one. myscript.qsh -o -n mydata.dat Options can be grouped together behind one hyphen. The following commands should be equivalent to the previous two. myscript.qsh -no mydata.dat myscript.qsh -on mydata.dat I have said "should be" twice in the preceding paragraphs because it is up to the programmer to make sure the script can handle any of these forms in the same way. It is also common in Unix shell programming to permit the use of a double hyphen (--) to indicate the end of the options and the beginning of the non-options. In the following example, the n option is specified. The value mydata.dat is an argument, but it is not an option argument. myscript.qsh -n -- mydata.dat An option may take an argument of its own. Consider the following command. myscript.qsh -n -f mydata.dat -p mydata.prn -z Three options were passed to the script: n, f, and p. The f option takes an argument: mydata.dat. The p option takes an argument: mydata.prn. The n and z options do not take arguments of their own. Extracting Argument Values When you write a script, you have to consider two things about arguments. Will the script accept option arguments? Will the script require a fixed number of arguments? Case 1 The easiest case is when there is a fixed number of arguments and none of them are options. In this case, the meaning of each argument is determined by its position in the list. For example, the following two commands are not equivalent. myscript mydata.dat yourdata.dat myscript yourdata.dat mydata.dat When the script begins, use the special parameter $# to be sure the correct number of arguments was passed. If there were too few or too many, send a message to stderr and exit with a non-zero status code. The following example verifies that exactly three arguments were passed to the script.
# make sure correct number of arguments was passed
if [ "$#" -ne 3 ]
then echo "Usage: ${0#$PWD/} pattern fromfile tofile" >&2
exit 1
fi
If this code is part of script myscript.qsh, the echo sends the following message to stderr. Usage: myscript.qsh pattern fromfile tofile Case 2 It is likewise easy to handle the situation in which there is a variable number of arguments and none of them are options. You must test for the parameters and take action accordingly. In the following example, Qshell writes the value of variable somevar to the file named in parameter 2 if at least two arguments were passed to the script. If the user passed only one argument, the echo is not carried out. if [ -n $2 ] then echo $somevar >$2 fi Case 3 The last case to consider is that of using options. Options must precede the non-option arguments. The usual method for handling options is to process the option arguments first, shift them out, then process the remaining arguments as in the previous two cases. The getopts utility makes easy work of processing the options. Its syntax is as follows. getopts option-string variable The option string lists the expected options, with no preceding hyphen. Follow an option that takes an argument of its own with a colon (:). Consider the following option string. while getopts bcd:kt: argname The script is written to expect five options: b, c, d, k, and t. The d and t options are expected to be followed by arguments. Each time getopts is executed, Qshell returns another option from the command line. The name of the option is stored in the variable without a preceding hyphen. If the option is expected to have an argument, that argument's value is stored in the special variable OPTARG. Assume a script that permits three options: v, f, and p. The f option is to be followed by a file name. One or more non-option arguments may follow the options. The following fragment shows how such a script would process the options.
# process the options
vflag=off
pflag=off
while getopts vf:p argname
do
case $argname in
v) vflag=on;;
p) pflag=on;;
f) filename=$OPTARG;;
esac
done
# get rid of options
shift $OPTIND-1
# process the remaining arguments
echo arg1 is $1
echo vflag is $vflag
echo pflag is $pflag
if [ -n "$filename" ]
then echo file name is $filename
else echo file name was not specified
fi
Let's look at this script in more detail. First, two variables, vflag and pflag, are given an initial value of off. Next, a while loop extracts the options. This loop continues, extracting one option at a time, until all the arguments have been processed. As each argument is processed, the case structure modifies at most one variable. If the v option is found--that is, if it was specified on the command line--the vflag variable will be changed to the value on. The same occurs for the p argument and the pflag variable. If the f option is encountered, Qshell stores the argument following that option into variable OPTIND, from which this script copies the value to variable filename. When the while loop ends, vflag will have a value of on or off, pflag will have a value of on or off, and filename will either be empty or have a value from the command line. These variables can be used later in the script as needed. The shift command removes the options. The OPTIND (option index) variable is one that you do not usually need. Qshell uses it to keep up with its place in the list of options. After Qshell has finished processing all the options, OPTIND will have a value one greater than the number of arguments in the option list. That is the reason why shifting OPTIND minus one argument removes all the options. Because of the shift, the first argument that follows the options becomes the new parameter 1. No More Options If you're accustomed to writing programs in RPG, COBOL, or CL, the idea that a certain value, such as a file name, could be in the first argument, or the fifth, or the twelfth, may cause you some stress. I hope this article has shown you that making sense of command-line arguments in Qshell scripts is no big deal.
|
Editors
Contact the Editors |
|
Last Updated: 9/12/02 Copyright © 1996-2008 Guild Companies, Inc. All Rights Reserved. |