1. Overview

In this tutorial, we’ll discuss the use cases for defining aliases, using Bash functions, and creating new shell scripts. First, we’ll review the salient features of these three Bash tools. Then, we’ll dive into the discussion of the use cases based on their unique features.

2. Background

Let’s take a closer look at the features that Bash aliases, functions, and scripts provide us.

2.1. Salient Features of Bash Aliases

Bash aliases are a way to create a shorthand for a long command or a sequence of commands. We can create an alias in Bash using the alias command:

$ alias rm='rm -i'

This will ensure that whenever we type the rm command on the terminal, Bash will replace it with rm -i. Consequently, we’ll be using the interactive mode for every delete operation:

$ touch testfile && rm testfile
rm: remove regular empty file 'testfile'? n
$

We can make this alias permanent by placing it in the ~/.bashrc file, and it will be available to interactive subshells. We can print all the available aliases by using the p option:

$ alias -p
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

By default, aliases are not available in shell scripts — for instance, in non-interactive shells. However, we can enable them using the shell option:

shopt -s expand_aliases

Moreover, ~/.bashrc is not read by shell scripts, hence, we must explicitly source the ~/.bashrc file if it contains aliases we want to make use of:

#!/bin/bash
shopt -s expand_aliases
source $HOME/.bashrc
alias welcome='echo "Welcome to the tutorial!"'
welcome

Let’s also execute the script to verify the output:

$ ./test_alias.sh
Welcome to the tutorial!

We should try to limit the use of aliases within shell scripts. The script can break if aliases are removed or if it’s executed in a different environment.

2.2. Salient Features of Bash Functions

Similar to aliases, we can also add functions to the Bash startup files. We can check the list of all functions available in the shell using the typeset command:

$ typeset -F | tail -10
declare -f _usergroup
declare -f _userland
declare -f _variables
declare -f _xfunc
declare -f _xinetd_services
declare -f command_not_found_handle
declare -f dequote
declare -f quote
declare -f quote_readline
declare -f welcome

Here, we’ve added the tail command to print only the last 10 lines on the terminal. Further, we can read the source code of our Bash function:

$ declare -f welcome
welcome ()
{
    echo "Welcome to the tutorial, $1. Good to have you here!"
}

Let’s test our welcome Bash function:

$ welcome Shubhneesh
Welcome to the tutorial, Shubhneesh. Good to have you here!

As we can see, the functions are much more feature-rich than aliases. Functions are more programmatic, and we can use loops and conditions within them. Most importantly, we can pass arguments to functions.

Another important aspect of functions is that we can export them. This makes them available to shell scripts that are executed from the environment in which they’re defined. Let’s export our function:

$ export -f welcome

We can add this statement to the ~/.bashrc startup file.

Now, it is legitimate to add Bash functions and export them within the ~/.bashrc file. But, if we have a large number of functions, it may be more practical to keep them in a separate hidden file ~/.bash_functions and source it within the ~/.bashrc file. This has the added advantage of keeping our ~/.bashrc file relatively clean.

The contents of aliases and Bash functions are held in the memory of the shell. As a result, no new subshell is created to execute them.

2.3. Salient Features of Bash Scripts

Bash scripts are not kept in the shell’s memory. Whenever a script is executed, a new subshell (non-interactive shell) is forked to execute the script. And within the subshell, the script is executed by the interpreter specified in the shebang line (for example, #!/bin/bash). But, if required, we can also execute the script within the current shell using the source command.

Let’s create a simple script to parse a CSV file:

#! /bin/bash
while IFS="," read -r rec_column1 rec_column2 rec_column3 rec_column4
do
  echo "Displaying Record-$rec_column1"
  echo "Record2: $rec_column2"
  echo "Record3: $rec_column3"
  echo "Record4: $rec_column4"
  echo ""
done < <(tail -n +2 input.csv)

This script reads a CSV file having 4 columns and prints the values on the terminal.

3. Understanding the Use Cases

Let’s now dive into discussions around the use cases of Bash aliases, scripts, and functions.

3.1. When to Create Bash Aliases

The use cases of aliases are pretty straightforward. If we use a command or short sequence of commands too often, we should probably try to create an alias for it. An example would be to create an alias to show git logs in a pretty-print and graphical format:

$ alias glog='git log --graph --abbrev-commit --decorate --date=relative --all'

Henceforth, we can simply type glog on the terminal as a shorthand to the above command.

3.2. When to Write Bash Functions

As we’ve seen in the previous sections, aliases have certain limitations. If there’s something we do repetitively that’s too complex to be an alias, we should create a Bash function. For example, we might want to create a function to execute a sequence of git commands:

Functions are like in-memory shell scripts. So, if we want to modify the environment of the current shell, like changing the working directory or setting environment variables, we should prefer functions over shell scripts.

Let’s create a function to traverse up the directory structure:

function traverse_up() 
{
    new_dir=""
    up_dir="$1"
    
    for i in `seq 1 $up_dir`;
    do
    new_dir="$new_dir"'../'
    done
    cd $new_dir
    echo $PWD
}
export -f traverse_up

Once we’ve set this function in the current environment, we can test it:

$ echo $PWD && traverse_up 3
/home/shubh/bael/tutorials/linux-bash/functions
/home/shubh/bael

Here, using traverse_up 3 is as good as typing the cd ../../.. command.

3.3. When to Code Bash Scripts

Finally, a script is something that ideally should be independent of the environment and should stand on its own. If something is a non-repetitive task or a utility that we would rarely use, we should create a script for it rather than an alias or a function.

Whenever we want to extend the functionality beyond the current shell, or if we need programs besides our shell to tap into such functionality, we should create a script for it.

4. Conclusion

In this article, we’ve learned the various use cases of Bash aliases, functions, and scripts.