Shell functions versus shell scripts

December 14, 2011

As part of Sysadvent I recently read Jordan Sissel's Data in the Shell, where one of his examples was a suite of tools for doing things with field-based data (things like summing a field). I approve of this in general, but there's one problem: he wrote his tools as shell functions. My immediate reaction was some approximation of a wince.

I have nothing against shell functions; I even use them in scripts sometimes, because they can be the best tool for the job. But using shell functions for tools like this has one big drawback: shell functions aren't really reusable. Jordan's countby function is neat, but if he wants to use it in a shell script he's out of luck; he's going to have to put a copy of the shell function in the shell script. If it was a shell script, he could have used it interactively just as he did and he could have reused it in future shell scripts.

Your default should always be to write tools as shell scripts. As nifty as they may be, shell functions are for two special cases; when you need to manipulate the shell's current environment or when you are absolutely sure that what you're writing will only ever be used interactively in your shell and never in a shell script (even a shell script that you wrote purely to record that neat pipeline you put together and may want some day in the future). Frankly, there are very few tools that you will never want to reuse in shell scripts, most especially if the reason you're writing them in the first place is to make pipelines work better.

(Shell scripts are also generally easier to write and debug, since you can work on them in a full editor, try new versions easily, and run them under 'sh -x' and similar things. They are also more isolated from each other.)

By the way, I'll note that I've learned this lesson the hard way. When I started out with my shell I wrote a lot of things as shell functions; over time it's turned out that I want to use many of them as shell scripts for various reasons and so I've quietly added shell script versions of any number of them. If I was clever I would do a systematic overhaul of my remaining shell functions to sort out what I no longer use at all, what should be a shell script, and what needs to remain as a function.


Comments on this page:

From 66.134.136.66 at 2011-12-14 05:40:42:

This is one reason I suppose I ought to figure out how to package stuff in Python. Copying the same set of functions and classes gets old after a while. A few of them don't even have better versions in the standard library.

-smarry

By jay at 2015-09-07 20:27:55:

korn shells have FPATH for looking up functions in files named after the function, I believe that you can emulate that in bash with autoload

Written on 14 December 2011.
« I'm on Twitter now
What makes backups real »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Wed Dec 14 01:43:18 2011
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.