Think of aliases as nicknames. You might have a command that you perform a lot but want to shorten.
As an example, you often want to go straight to desktop in commandline, so you can do this
alias desktop="cd ~/Desktop"
From then on you just type
desktop
in terminal and it will perform the cd ~/Desktop
for you.
Functions contains logic. In a function, you might make calls to several different programs. Here's a simple echo function
function e {
echo $1
echo $1 $1
echo $1 $1 $1
}
While it may appear similar to an alias when you call it
e Hello
Your e() can have a lot of different things happen. The above is a simplistic example.
Aliases should be reserved for simple use cases. Personal example - I have replaced my rm
command like this
alias rm='trash-put'
Whenever I do an rm, it will send it to trash instead of deleting it from disk. This caters to my clumsiness in the terminal where I may (sometimes) accidentally delete an important file.
Functions, you need to remember, are pieces of logic. You wouldn't use a function standalone, usually. It would be part of a larger script. Imagine a script which takes all of your files and renames them to their pig latin versions. Ignore that there are different ways of doing it.
But what you could do is loop through every file in the directory and pass the filepath to your RenameAsPigLatin function. The RenameAsPigLatin function might have extra logic in there involving numbers, where you decide that files ending with numbers shouldn't be renamed.
Immediately you can see the benefit of having it as a function. The function can focus on the renaming by your strange rules while the rest of the script can traverse various directories as necessary.
As is the case with most programming, solving the problem was extremely hard. I had to study a bunch about Bash variables, and how to use export
and source
(or the POSIX dot operator, .
), and how bash loads, and what interactive -i
bash mode was, etc etc.
I found man bash
and man test
to also be useful. Here's how to do what I want to do, which is:
- Write a script to open 3 tabs.
- cd into a different folder in each tab (ie: run a unique command).
- get each tab to have a unique title by modifying its local PS1 variable
- Ensure each tab stays open after the script is run
1st, add this to the bottom of your ~/.bashrc
file:
# Function to allow a user to arbitrarily set the terminal title to anything
# Example: `set-title this is title 1`
set-title() {
# Set the PS1 title escape sequence; see "Customizing the terminal window title" here:
# https://wiki.archlinux.org/index.php/Bash/Prompt_customization#Customizing_the_terminal_window_title
TITLE="\[\e]2;$@\a\]"
PS1=${PS1_BAK}${TITLE}
}
# Back up original PS1 Prompt 1 string when ~/.bashrc is first sourced upon bash opening
if [[ -z "$PS1_BAK" ]]; then # If length of this str is zero (see `man test`)
PS1_BAK=$PS1
fi
# Set the title to a user-specified value if and only if TITLE_DEFAULT has been previously set and
# exported by the user. This can be accomplished as follows:
# export TITLE_DEFAULT="my title"
# . ~/.bashrc
# Note that sourcing the ~/.bashrc file is done automatically by bash each time you open a new bash
# terminal, so long as it is an interactive (use `bash -i` if calling bash directly) type terminal
if [[ -n "$TITLE_DEFAULT" ]]; then # If length of this is NONzero (see `man test`)
set-title "$TITLE_DEFAULT"
fi
2nd, create this script to open 3 unique tabs with 3 unique cd commands and 3 unique titles:
open_tabs.sh:
gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='title 1'; cd ..; exec bash;"
gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='title 2'; cd ../..; exec bash;"
gnome-terminal --tab -- bash -ic "export TITLE_DEFAULT='title 3'; cd ../../..; exec bash;"
Now open up a terminal and run the open_tabs.sh
script:
./open_tabs.sh
Voila! It's magical! These 3 new tabs are now shown at the top of my terminal, and each has done the proper cd
command I set, and each has the proper title I set!

This will all be placed into my dotfiles project: https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.
Full and final solution: see here: Open Terminal with multiple tabs and execute application
Best Answer
If you define these in your
~/.bash_aliases
file, which is an Ubuntu-specific thing and gets sourced by~/.bashrc
in a default Ubuntu install, then yes, there is an overhead since the file will be sourced each time you start a new interactive, non-login shell. So each time you open a new terminal window, for example. Now, with modern machines, this overhead will most likely be undetectable, but it can be an issue for older machines, embedded systems or if you start having loads of complex functions defined.In addition, functions and aliases defined this way are not accessible to scripts by default. So if you want to use one of those functions in your scripts, you will need to source
.bashrc
(or.bash_aliases
) explicitly. If you have them as external script files in your$PATH
, that won't be needed.My personal rule of thumb comes down to the complexity of the commands involved and whether or not the function/script I am writing is likely to be useful to non-interactive shells (e.g. other scripts). If I find myself writing several dozen lines of code, then I'll likely move it to a script. If I'm writing something that can be used in many different contexts and can likely come in handy when writing another script then, again, I'll move it to a script.
If, however, I just want a simple little function like the one you show in your question, that's only really useful when run interactively, then I'll stick to functions. So it really is a matter of your own personal preference and considering how and when you will want to use the functions you are defining.