11

I have read this thread about where to put aliases.

Now, let's suppose that my custom command is quite elaborate (takes arguments in input, is composed of several commands run one after the other, I want to preserve it multi-line for clarity's sake, involves quotes, double quotes, etc.), so I want to define it as a function, e.g.

sshdev_system_loop () {
        while true; do
          echo "[$(date +'%Y-%m-%d %H:%M:%S')] Trying to log into ststem $2 as user $1 ."
          timeout 10 ssh $1@$2
        done
}

shall I put it in .bash_aliases or at the end of .bashrc or in .profile?

On one hand I don't want to put it in .bash_aliases since it will "spoil" the list of

alias alias_name='command/list of commands'

and on the other hand, .bashrc looks like a file administrated by the OS, so I don't want to add things to it.

So what is the best practice to add functions as custom commands in Ubuntu?

Raffa
  • 34,963
Tms91
  • 595

2 Answers2

12

It is largely up to you and how you use your computer. bash_aliases is not a standard file, this is something Ubuntu adds to the system. If you look at Ubuntu's default .bashrc (/etc/skel/.bashrc), you will see:

if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

Ubuntu sets itself up to source (read) that file (the . means read the file into the current shell) if it exists. So if you are planning to migrate your setup somewhere else, don't use bash_aliases at all.

If you only care about Ubuntu, then using bash_aliases or bashrc is the same thing. They will both be read at the same time since one sources the other, so the choice of which one to use is up to you.

That said, the .bashrc file is absolutely intended to be edited by the user and not to be administered by the OS, so you should feel free to edit it. Traditionally, you would put aliases and functions in ~/.profile, however, since .bashrc is read every time you start a new interactive non-login shell, while .profile is only read by interactive login shells. In practice, on a modern graphical system, that means that .bashrc (and .bash_aliases on Ubuntu) is read every time you open a new terminal, while .profile will be read only when you log in. So people would try to keep .bashrc streamlined so it wouldn't take too long to be read each time. However, on modern systems, it really doesn't make any noticeable difference. Our machines are fast enough to read larger files with no issue at all.

Another consideration is that .profile and .bashrc are read by different kinds of shell, login and non-login respectively as mentioned above. See my answers here and here for more details on this. The point is that on traditional systems, when running a non-login shell, .profile is not read. however, Ubuntu like its parent Debian, has a special line in its .profile that sources .bashrc:

$ grep -A1 bashrc /etc/skel/.profile 
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi

All this means that you can add functions to your .bashrc or .bash_aliases files as you like, and they will still be available to login shells. You might want to use .profile instead, but feel free to use .bashrc. That's what it's for: for the user to define extra stuff for their shell.

Some useful references:

terdon
  • 104,119
10

A little twist on Terdon's excellent answer:

I've chosen the solution to add a new block to my .bashrc with the following contents:

if [[ -f ~/.bash_functions ]]
then
  . ~/.bash_functions
fi

As you can see, the principle is exactly the same as for .bash_aliases, except I prefer to have my functions defined in a separate file .bash_functions.

Then, there's yet another twist to it. When I define my function, I do it like this:

# Go up in directory structure
_up() {
  local d=""
  local limit="$1"

Default to limit of 1

if [ -z "$limit" ] || [ "$limit" -le 0 ]; then limit=1 fi

for ((i=1;i<=limit;i++)); do d="../$d" done

cd "$d" }

And then, I actually reference the function in my .bash_aliases file:

alias up='_up'

In that way, my function shows up in the alias list when I just run alias, but since it starts with _, I know it's a function that's defined in .bash_functions.

Artur Meinild
  • 31,035