Executing Korn Shell Scripts

Let's make a Korn shell script out of the print Hello world command by putting it into a file like this:

					$ print "print Hello world" >prhello
				

Before Korn shell scripts can be executed, they must be made executable by setting the execute and read bits with the chmod command:

					$ chmod 755 prhello
				

or

					$ chmod +rx prhello
				

Assuming that the current directory is in the search path $PATH, prhello can now be executed by simply invoking it by name:

					$ prhello
					Hello world
				

Korn shell scripts can also be executed by invoking them as the first argument to ksh:

					$ ksh prhello
					Hello world
				

Now we can use prhello like any other command. The output can be directed to a file:

					$ prhello >p.out
					$ cat p.out
					Hello world
				

It can be used with a pipe:

					$ prhello | wc
					1      2     12
				

or with command substitution:

					$ print "We always say "$(prhello)""
					We always say "Hello world"
				

By default, Korn shell scripts are run in a separate environment. This means that variables from the current environment are not available to Korn shell scripts unless explicitly exported, and variables defined in Korn shell scripts are not passed back to the parent shell. Just to prove it, here is a demonstration. The checkvar Korn shell script does just one thing: it prints the value of LOCALVAR.

					$ cat checkvar
					print "LOCALVAR is set to: $LOCALVAR"
				

If LOCALVAR is set to something in the current environment, and checkvar is run, we see that LOCALVAR is not defined:

					$ LOCALVAR="This is the original value"
					$ checkvar
					LOCALVAR is set to:
				

If we export LOCALVAR, then its value will be available to checkvar:

					$ typeset —x LOCALVAR
					$ checkvar
					LOCALVAR is set to: This is the original value
				

To show that Korn shell script environments cannot modify variable values in the parent shell, we'll change checkvar to reassign a value to LOCALVAR.

					$ cat checkvar
					print "LOCALVAR is set to: $LOCALVAR"
					LOCALVAR="This is a new value"
					print "The new LOCALVAR is set to: $LOCALVAR"
				

Now when it is run, LOCALVAR is set to the new value:

					$ checkvar
					LOCALVAR is set to: This is the original value
					The new LOCALVAR is set to: This is a new value
				

Meanwhile, back in the parent shell, LOCALVAR has not been affected.

					$ print $LOCALVAR
					This is the original value
				

If the allexport option is enabled (set –a, or set – o allexport), variables are automatically exported when defined. By default, this option is disabled.

Positional Parameters

Positional parameters are special variables used to keep track of arguments to the Korn shell, scripts, and functions. Positional parameter names contain only digits and cannot be set directly using variable=value syntax. By default, parameter zero (or $0) is set to the name of the shell, script or function.

						$ print $0
						/bin/ksh
					

The remaining parameters 1 to n are set to each of the arguments passed to the shell, script or function. For example, if you invoke a Korn shell script called ptest and pass the arguments A, B, and C, then in the script ptest, $0 would be set to ptest, $1 to A, $2 to B, and $3 to C.

Table 8.1. Positional Parameters
$0 name of script or function or pathname of Korn shell for set
$n nth argument to script, function, or set
${n} nth argument to script, function, or set when n is greater than 9
$# number of positional parameters
$*, $@ all positional parameters separated with a blank
"$*" all positional parameters enclosed in double quotes
${*:X} all X to the last positional parameters
"${*:X}" all X to the last positional parameters enclosed in double quotes
${*:X:n} n positional parameters beginning with Xth
"${*:X:n}" n positional parameters beginning with Xth enclosed in double quotes

There are three special Korn shell variables that provide information about the current positional parameters. The first is $#, and it contains the number of positional parameters. The other two are $@ and $*, and they both contain all the positional parameters. So in the above ptest example, $# would be 3, and both $* and $@ would be A B C. Here is a Korn shell script that manipulates positional parameters. It displays the name of the current script, the number of positional parameters, and the value of each of the positional parameters:

						$ cat check_params
						print "Script name:              $0"
						print "Number of args passed:    $#"
						print "Arguments passed:         $*"
						print "Arg 1=$1, Arg 2=$2, Arg 3=$3"
					

If executed with no arguments, this is the output:

						$ check_params
						Script name:              check_params
						Number of args passed:    0
						Arguments passed:
						Arg 1=, Arg 2=, Arg 3=
					

while if executed with the arguments A and B, the output is:

						$ check_params A B
						Script name:              check_params
						Number of args passed:    2
						Arguments passed:         A B
						Arg 1=A, Arg 2=B, Arg 3=
					

Modifying Positional Parameters

By default, $0 is set to the name of the shell, script or function. It cannot be set or modified. The remaining parameters from $1 to $n can be reassigned with the shift command.

The shift command, with no arguments, shifts positional parameters left once, so that $1 takes the value of $2, $2 takes the value of $3, and so on. The original value of $1 is lost.

Let's change the check_params script so that it shifts the positional parameters left once:

							$ cat check_params
							print "Script name:              $0"
							print "Number of args passed:    $#"
							print "Arguments passed:         $*"
							print "Arg 1=$1, Arg 2=$2, Arg  3=$3"
							shift
							print "Number of remaining args: $#"
							print "Remaining args:           $*"
							print "Arg 1=$1, Arg 2=$2, Arg 3=$3"
						

When we run it again with the arguments A B, we get:

							$ check_params A B
							Script name:                     check_params
							Number of args passed:           2
							Arguments passed:                A B
							Arg 1=A, Arg 2=B, Arg 3=
							Number of remaining args:        1
							Remaining args:                  B
							Arg 1=B, Arg 2=, Arg 3=
						

After the shift command, $1 is set to B and $2 is unset. The original value of $1 is lost.

The positional parameters can be shifted left more than once by providing an integer argument to the shift command: shift n.

Now let's try something else with positional parameters. Here is a Korn shell script called kuucp. It uses uucp to copy a file to the public directory on the rnihd system.

							$ cat kuucp
							PUBDIR=${PUBDIR:—/usr/spool/uucppublic}
							uucp $1 rnihd!$PUBDIR/$1
							print "Copied $1 to rnihd!$PUBDIR/$1"
						

So instead of typing this long command line:

							$ uucp n.out rnihd!/usr/spool/uucppublic/n.out
						

we can do this:

							$ kuucp n.out
						

and in the script, $1 gets substituted with n.out in both the source and target file arguments. We could extend this further to be able to uucp files to any system by having a system name given as another command-line argument. Now $1 is used for the source and target file, and $2 for the remote system name.

							$ cat kuucp
							PUBDIR=${PUBDIR:—/usr/spool/uucppublic}
							uucp $1 $2!$PUBDIR/$1
							print "Copied $1 to $2!$PUBDIR/$1"
						

To send the file msg.c to the uucp public directory on the unisf system, kuucp would be invoked like this:

							$ kuucp msg.c unisf
						

$1 would be substituted with the msg.c, and $2 with unisf. Notice that the destination directory is taken from PUBDIR variable. If it's not set, the default uucp public directory is used.

The exit command

In Chapter 2, we learned that Unix programs return an exit status. And that a zero exit status indicates successful execution, while a non-zero exit status indicates failure. The exit command allows you to terminate execution from anywhere in a Korn shell script and return an exit value using this format:

							exit
						

or

							exit
							n
						

where n is the exit status to return. If n is not specified, the exit status of the previous command is used. If you don't use exit, then scripts finish after the last command is executed.

Take a look at the kuucp script again. What happens if an error occurs? For example, if the file argument is entered incorrectly, or it doesn't exist? The uucp command will fail, but the status message following will still get displayed. Here is a good place for exit. It could be used to terminate execution and return a non-zero exit status if for some reason the uucp command failed. To get the exit status, $? is checked after uucp is run. If it is non-zero, then we display our own error message and exit. Otherwise, the next command is executed and the script terminates successfully.

							$ cat kuucp
							PUBDIR=${PUBDIR:—/usr/spool/uucpublic}
							uucp $1 $2!$PUBDIR/$1 2>&—
							(($? != 0)) && {print "Got uucp error"; exit 1;}
							print "Copied $1 to $2!$PUBDIR/$1"
						

By the way, the 2>&– just traps the uucp error messages. We don't need to see them anymore, since kuucp is now doing its own error processing. Now when kuucp is run on a non-existent file, this is what happens:

							$ kuucp nofile unisf
							Got uucp error
							$ print $?
							1
						

The exit command does one more thing. If given at the command prompt, it terminates your login shell.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.154.89