Bash Shell Scripting/Shell Functions

A shell function is a special type of variable that is essentially a script-within-a-script. This feature allows us to group a sequence of commands into a single named command, which is particularly useful if the sequence of commands needs to be run from many places within the script. A shell function can even consist of just a single command; this may be useful if the command is particularly complicated, or if its significance would not immediately be obvious to a reader. (That is, shell functions can serve two purposes: they can save typing, and they can allow for more readable code by creating intuitively-named commands.) Consider the following script:

The above script creates a shell function called  that asks the user to type a password, and stores the result in a specified variable. It then runs  to store the password as  ; and lastly, if the call to   succeeded (as determined by its exit status), the retrieved password is printed to standard output (which is obviously not a realistic use; the goal here is simply to demonstrate the behavior of  ).

The function  doesn't do anything that couldn't be done without a shell function, but the result is much more readable. The function invokes the built-in command  (which reads a line of user input and saves it in one or more variables) with several options that most Bash programmers will not be familiar with. (The  option disables a special meaning for the backslash character; the   option causes a specified prompt, in this case , to be displayed at the head of the line; and the   option prevents the password from being displayed as the user types it in. Since the   option also prevents the user's newline from being displayed, the   command supplies a newline.) Additionally, the function uses the conditional expression   to make sure that the script's input is coming from a terminal (a console), and not from a file or from another program that wouldn't know that a password is being requested. (This last feature is debatable; depending on the general functionality of the script, it may be better to accept a password from standard input regardless of its source, under the assumption that the source was designed with the script in mind.) The overall point is that giving sequence of commands a name —  — makes it much easier for a programmer to know what it does.

Within a shell function, the positional parameters (, , and so on, as well as  ,  , and  ) refer to the arguments that the function was called with, not the arguments of the script that contains the function. If the latter are needed, then they need to be passed in explicitly to the function, using. (Even then,  and   will only affect the positional parameters within the function, not those of the caller.)

A function call returns an exit status, just like a script (or almost any command). To explicitly specify an exit status, use the  command, which terminates the function call and returns the specified exit status. (The  command cannot be used for this, because it would terminate the entire script, just as if it were called from outside a function.) If no exit status is specified, either because no argument is given to the   command or because the end of the function is reached without having run a   command, then the function returns the exit status of the last command that was run.

Incidentally, either  or   may be omitted from a function declaration, but at least one must be present. Instead of, many programmers write. Similarly, the  notation is not exactly required, and is not specific to functions; it is simply a notation for grouping a sequence of commands into a single compound command. The body of a function must be a compound command, such as a  block or an   statement;   is the conventional choice, even when all it contains is a single compound command and so could theoretically be dispensed with.