|
BigAdmin System Administration Portal
Community Submitted Article
|
|
Converting a ksh Function to a ksh ScriptWilliam R. Seppeler, April 2006 DescriptionHere is a simple way to create a script that will behave both as an executable script and as a ksh function. Being an executable script means the script can be run from any shell. Being a ksh function means the script can be optimized to run faster if launched from a ksh shell. This is an attempt to get the best of both worlds. Procedure
Start by writing a ksh function. A ksh function is just like a ksh script except the script code is enclosed within a Take the following example:
# Example script
function fun {
print "pid=$$ cmd=$0 args=$*" opts="$-"
}
Save the text in a file. You'll notice nothing happens if you try to execute the code as a script: ksh ./example In order to use a function, the file must first be sourced. Sourcing the file will create the function definition in the current shell. After the function has been sourced, it can then be executed when you call it by name: .. ./example fun To make the function execute as a script, the function must be called within the file. Add the bold text to the example function.
# Example script
function fun {
print "pid=$$ cmd=$0 args=$*" opts="$-"
}
fun $*
Now you have a file that executes like a ksh script and sources like a ksh function. One caveat is that the file now executes while it is being sourced. There are advantages and disadvantages to how the code is executed. If the file was executed as a script, the system spawns a child ksh process, loads the function definition, and then executes the function. If the file was sourced, no child process is created, the function definition is loaded into the current shell process, and the function is then executed. Sourcing the file will make it run faster because no extra processes are created, however, loading a function occupies environment memory space. Functions can also manipulate environment variables whereas a script only gets a copy to work with. In programming terms, a function can use call by reference parameters via shell variables. A shell script is always call by value via arguments. Advanced Information
When working with functions, it's advantageous to use ksh autoloading. Autoloading eliminates the need to source a file before executing the function. This is accomplished by saving the file with the same name as the function. In the above example, save the example as the file name "
Notice the double output the first time
#!/bin/ksh
# Example script
function fun {
print "pid=$$ cmd=$0 args=$*" opts="$-"
}
[[ "${0##*/}" == "fun" ]] && fun $*
Now the file is a self-executing script as well as a self-sourcing function (when used with ksh autoloading). What becomes more interesting is that since the file can be an autoload function as well as a stand-alone script, it could be placed in a single directory and have both
# ${HOME}/.profile
FPATH=${HOME}/bin
PATH=${FPATH}:${PATH}
In this setup, ConsiderationsEven though the file can be executed as a function or a script, there are minor differences in behavior between the two. When the file is sourced as a function, all local environment variables will be visible to the script. If the file is executed as a script, only exported environment variables will be visible. Also, when sourced, a function can modify all environment variables. When the file is executed, all visible environment variables are only copies. We may want to make special allowances depending on how the file is called. Take the following example.
#!/bin/ksh
# Add arg2 to the contents of arg1
function addTo {
eval $1=$(($1 + $2))
}
if [[ "${0##*/}" == "addTo" ]]; then
addTo $*
eval print \$$1
fi
The script is called by naming an environment variable and a quantity to add to that variable. When sourced, the script will directly modify the environment variable with the new value. However, when executed as a script, the environment variable cannot be modified, so the result must be output instead. Here is a sample run of both situations. # called as a function var=5 addTo var 3 print $var # called as a script var=5 export var var=$(./addTo var 3) print $var
Note the extra steps needed when executing this example as a script. The Extra
|
| |||