Have you ever wondered why ZSH provides so many features but is still so fast? That's because of its autoloading mechanism. Functions can be marked as empty so they aren't loaded before they are executed the first time. This saves a lot of memory and much processing power.
The base of this autoloading mechanism is the shell parameter
$fpath. This variable contains all the paths where function definition files are located. You can view them with:
In current versions of ZSH this should give you a long list of directories all containing files with function definitions. We can also add our own directory to it:
mkdir myfndir fpath=($fpath myfndir)
$fpath is not a delimiter separated string. It is an array. So just adding
mydir using string concatenation would break your shell!
Now that we have added our own directory we can create our first function. Normally functions always have a function definition and body. However, the files for autoload functions only contain the body. So to create an autoload function
foobar we need to create a file called
foobar inside our autoload directory with the body of our function (without any surrounding braces):
# Some autoload function echo "Hello World"
Until now nothing happens when we call
foobar on the command line. That's because we haven't marked it for autoloading yet. To do that run:
This will mark the function for autoloading. It is important to know that the function has not yet been executed in any way.
autoload just creates an empty function definition. The function body will be loaded from the file the first time the function is called. You can prove that by renaming our file and calling the function:
mv myfndir/foobar myfndir/foobarbaz foobar
You'll get the error message zsh: foobar: function definition file not found. If you rename the file back:
mv myfndir/foobarbaz myfndir/foobar
and call the function again, the file will be loaded into memory for execution without any problems. If you now rename the source file again, the function will still be able to run.
This autoloading mechanism ensures that the shell stays fast and snappy even though it provides a lot of features. Marking functions to be autoloaded with the
autoload command only has a very small memory footprint.
Now you should be able to write your own autoload functions, but before we call it quits for today let me show you one more very important thing. You might have noticed the
-U parameter I used in some of the previous articles when I invoked the
autoload command. This parameter prevents the expansion of aliases. Imagine what would happen if you had an autoload function called
myfunction with the following contents:
echo "This is some example file"
And you had the following alias definition in your
alias echo="shutdown -h now"
If we'd load and execute our function as root
autoload myfunction myfunction
it would be a big surprise what it actually does. Okay, I admit: you normally wouldn't alias
shutdown or something similar, but I think you know what I mean. Custom alias definitions could break some functions. In the best case the function would only be unable to run. In the worst case it might do some dangerous stuff. The
-U parameter prevents alias expansion inside autoload functions. Even though you had aliased
rm -R / the function would still work properly without any unintended side-effects. Therefore it is a good idea to autoload all functions with this parameter unless you know what you do.
Read more about autoloading functions: