Shell aliases that make Drupal administration easier

In my daily work with Drupal development and Drupal hosting, some few aliases are really handy. In this blog post, I will share some of these. But first, a little introduction to what aliases are and how to setup them.

About aliases

What is an alias?

An alias is a word, e.g. ll, that at the beginning of a command line is interpreted by the shell as a string, e.g. ls --color=auto -F -l -h. The command

alias <name>=<value>

defines <name> as an alias for the string <value>. Thus, to define ll as an alias for ls --color=auto -F -l -h, you enter following at your shells command line:

alias ll='ls --color=auto -F -l -h'

The alias command is available in all POSIX-conformant systems, including Unix, Linux, Mac OS X and some Windows versions. In reality, the exact behavior of alias depends on the shell. I will therefore assume the Bourne-again shell, more known as (Bash), which is the default shell on most systems built on top of the Linux kernel as well as on Mac OS X.

Aliases and arguments

With the above alias, it is possible to enter ll /home/thomas to list the files in my home directory. This is possible because the substitution of the alias is done before the command is interpreted. Thus, the shell interprets ll /home/thomas as ls --color=auto -F -l -h /home/thomas, which makes perfectly sense.

But what to do if the words following the alias are needed within the aliased string? For instance, assume we want rmr <pattern> to be an alias for rm -rfv $(find . -name "<pattern>" -printf " %p"). That can't be done with alias. The solution is to define a function instead. The rmr alias could be defined as follows:

rmr () { rm -rfv $(find . -name "$1" -printf " %p") ; }

Now, we can enter, for instace, rmr CVS to recursively delete all files and directories which name is CVS, or, for another example, rmr "*~" to recursively delete all files and directories ending with a tilde.

Permanent aliases

Unfortunately, aliases and functions remains in effect only in the shell they are defined. Thus, if you logout and login, or start another shell, they don't apply. To solve that, you can create the file ~/.bash_aliases in your home directory, and make Bash read it every time a shell is created by adding following lines at the end of ~/.bashrc in your home directory:

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

Nota bene: Your ~/bashrc file might already contain aliases. I recommend you comment out those lines, to make ~/.bash_aliases the only place where aliases are defined. On Ubuntu, that means your ~/.bashrc file should look like this near the end:

# Alias definitions. # You may want to put all your additions into a separate file like # ~/.bash_aliases, instead of adding them here directly. # See /usr/share/doc/bash-doc/examples in the bash-doc package. if [ -f ~/.bash_aliases ]; then . ~/.bash_aliases fi # enable color support of ls and also add handy aliases #if [ -x /usr/bin/dircolors ]; then #eval "`dircolors -b`" #alias ls='ls --color=auto' #alias dir='dir --color=auto' #alias vdir='vdir --color=auto' #alias grep='grep --color=auto' #alias fgrep='fgrep --color=auto' #alias egrep='egrep --color=auto' #fi # some more ls aliases #alias ll='ls -l' #alias la='ls -A' #alias l='ls -CF'

My aliases

ls

On Unix-like operative system one of the most used commands must be ls. Having aliases for the most common usages of ls, e.g. ll for ls --color=auto -F -l -h, can be a really timesaver. I therefore have following aliases in my ~/.bash_aliases:

# Enable color support of ls and classifying if [ -x /usr/bin/dircolors ]; then eval "`dircolors -b`" LS_OPTIONS='--color=auto -F' else LS_OPTIONS='-F' fi export LS_OPTIONS # Aliases for ls alias l="ls $LS_OPTIONS" alias ls="ls $LS_OPTIONS" alias la="ls $LS_OPTIONS -a" alias ll="ls $LS_OPTIONS -lh" alias ld="ls $LS_OPTIONS -d" alias lla="ls $LS_OPTIONS -alh" alias lld="ls $LS_OPTIONS -dlh"

With these aliases, l and ls list the files colorized and with one of the characters *, @ and / appended to indicate executable, symbolic link and directory, respectively. In addition, la lists hidden files as well, ll uses a long listing format with sizes in human readable format (e.g. 1K, 234M and 2G), and ld list directory entries instead of their contents. Finally, lla and lld are ll combined with with la and ld, respectively.

cd ..

When working with Drupal, I find myself repeatedly jump up and down in the directory structure. To save some time I therefore have following aliases in ~/.bash_aliases:

# Aliases for cd alias ..='cd ..' alias ...='cd ../..' alias ....='cd ../../..' alias .....='cd ../../../..' alias .....='cd ../../../../..'

Now, if I working in sites/moduels/all/simplenews_template and want to move to Drupal's home directory, I just enter ....., which only requires 5 key presses, instead of cd ../../../.., which requires 17 key presses including the Shift-key.

Don't forget that cd itself has some very useful shortcuts: cd - takes you to the previously visited directory, and cd only takes you back to your home directory.

hosts, a2reload and a2restart

As Drupal developer, I often need to setup local copies of sites on my laptop. To do that, I must, among other things, edit the /etc/hosts file and reload or restart the Apache web server. To facilitate that, I have following aliases in my ~/.bash_aliases:

# Web developer aliases alias hosts='sudo -E sensible-editor /etc/hosts' alias a2reload='sudo /etc/init.d/apache2 reload' alias a2restart='sudo /etc/init.d/apache2 restart'

What a2reload and a2restart do should be obvious. But what is sensible-editor in the hosts alias?

On Debian based GNU/Linux distributions, such as Ubuntu which I am using, sensible-editor is a command that starts the default editor. The default editor is set by the select-editor command. If the environment variables VISUAL or EDITOR are set, that value is used instead. On non Debian machines, you might want to replace sensible-editor with $VISUAL or $EDITOR or the path to your favorite editor, e.g. /usr/bin/emacs.

wtar

How often haven't you downloaded a tarball to just unpacked it and then deleted it? For example:

wget http://ftp.drupal.org/files/projects/drupal-6.13.tar.gz tar zxvf drupal-6.13.tar.gz rm drupal-6.13.tar.gz

Wouldn't it be nice to download and unpack tarballs in one sweep? Well, with following in your ~/.bash_aliases it is possible:

# Download tarball and unpack it. wtar () { wget -q -O - $1 | tar zxv --no-same-owner --no-same-permission ; }

Now, the Drupal tarball above could be downloaded and unpacked in the current directory by just entering

wtar http://ftp.drupal.org/files/projects/drupal-6.13.tar.gz

For tarballs from Drupal.org, e.g. Drupal itself, modules and themes, you should however consider using Drush instead.

cvslogin

As maintainer of several Drupal modules, I often use CVS to check in and out files from Drupals contrib-repository. But before I can do that, I must set the environmental variable CVSROOT. But I have trouble to remember what it should be set to. I could of course look it up, but it is a lot easier to have following function in my ~/.bash_aliases:

# CVS login to Drupal.org's contrib-repository. cvslogin () { export CVSROOT=:pserver:$1@cvs.drupal.org:/cvs/drupal-contrib && cvs login ; }

With that, I can both set CVSROOT and login by just typing:

cvslogin tbarregren

~rm and rmr

Finally, I have two "cleanup" aliases in my ~./bash_aliases:

# Cleanup aliases alias ~rm='rm -f *~ .*~' rmr () { rm -rfv $(find . -name "$1" -printf " %p") ; }

The rationale behind ~rm, is safety. I'm using Emacs and gedit as text editors. Before saving changes to a file, both editors make a backup copy named as the original file with a tilde at the end. As an effect, after editing a file, e.g. relatedcontent.module, I also have another file relatedcontent.module~. Since it occasionally has saved my day, I want it to be that way. But it is annoying to have all these backup files laying around. I therefore delete them frequently. But the command to do that, rm *~ is just a key-press away from the disastrous rm *. So to prevent accidents, I write ~rm instead.

The function rmr takes things to another (and definitely non-safe) level. To begin with, it is recursively. While ~rm only deletes files in the current working directory, rmr "*~" deletes backup files in the current working directory as well as in subdirectories and their subdirectories and so on. And more, it can be used to delete other files than backup files. For an example, rmr CVS would delete all CVS-directories that cvs co creates.

The complete .bash_aliases file

The complete .bash_aliases file looks like this:

# Enable color support of ls and classifying if [ -x /usr/bin/dircolors ]; then eval "`dircolors -b`" LS_OPTIONS='--color=auto' else LS_OPTIONS='-F' fi export LS_OPTIONS # Aliases for ls alias l="ls $LS_OPTIONS" alias ls="ls $LS_OPTIONS" alias la="ls $LS_OPTIONS -A" alias ll="ls $LS_OPTIONS -lh" alias ld="ls $LS_OPTIONS -d" alias lla="ls $LS_OPTIONS -Alh" alias lld="ls $LS_OPTIONS -dlh" # Aliases for cd alias ..='cd ..' alias ...='cd ../..' alias ....='cd ../../..' alias .....='cd ../../../..' alias .....='cd ../../../../..' # Web developer aliases alias hosts='sudo -E sensible-editor /etc/hosts' alias a2reload='sudo /etc/init.d/apache2 reload' alias a2restart='sudo /etc/init.d/apache2 restart' # Download tarball and unpack it. wtar () { wget -q -O - $1 | tar zxv --no-same-owner --no-same-permission ; } # CVS login to Drupal.org's contrib-repository. cvslogin () { export CVSROOT=:pserver:$1@cvs.drupal.org:/cvs/drupal-contrib && cvs login ; } # Cleanup aliases alias ~rm='rm -f *~ .*~' rmr () { rm -rfv $(find . -name "$1" -printf " %p") ; }