Bash is one of those Unix things that I am fully aware has a lot more potential and power than I know how to use. Every so often I go looking for another handful of useful things to learn about it: this is a selection of recent ones.
Firstly: the Debian bash package includes a file /etc/bash_completion which extends bash - for example, enabling zsh-style tab completion of hostnames. Source this file in your own .bashrc to get this functionality. It also makes it easy to extend/program bash yourself, via the directory /etc/bash_completion.d/, which is automatically sourced by /etc/bash_completion. For example, suppose you have a script foo.sh which takes hostnames as arguments (e.g. one which applies a particular command across a set of hostnames). You can get hostname tab-completion on foo.sh by creating a file /etc/bash_completion.d/foo which contains the line
complete -F _known_hosts foo.shYou can also, of course, can get a lot more complicated - this article talks about getting tab-completion for any other arguments to
foo.sh.
Secondly: $CDPATH is to cd what $PATH is to executables. Set $CDPATH in your .bashrc as follows:
export CDPATH=.:~:/usr/local/:/opt/my/long/dir/pathThen if you wish to change to
/opt/my/long/dir/path/subdir, just type cd subdir at the prompt and you’re there. Note that you do need to include . in there or you won’t be able to change directories within your current directory.
Thirdly, some small useful .bashrc things:
shopt -s cdspellwill attempt to correct misspellings of directories.shopt -s dotgloballows files beginning with a dot to be returned in filename expansions.export HISTCONTROL=ignorebothstops the bash history from including either duplicate lines, or lines beginning with a space, which makes it rather quicker to navigate.
- Ctrl-r searches backwards in your bash history. I love this one very much.
- Alt-. (that’s a full stop there) inserts at the cursor the last argument to the previous command.
- Alt-Ctrl-y inserts at the cursor the first argument to the previous command. Further: if you hit Alt-3 then Alt-Ctrl-y, you’ll get the 3rd argument to the previous command.
Finally: a little snippet for your .bashrc that will change the title of your xterm or xterm-alike to show username@hostname:/current/directory. It updates as you change directory or ssh to another host. This is useful if you spend a lot of time opening lots of xterms on various hosts and in various directories; and it’s another visual clue as to (e.g.) whether you’re currently logged in as root. Myself, I also set my root prompts to be in a different colour to my own prompts. You can’t have too many reminders of your identity…
case $TERM in
xterm*)
PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}:${PWD}\007"'
;;
*)
;;
esac
Comments with other useful bash bits and pieces welcome!


Adding the CVS branch name to your prompt
If you tend to forget which branch you're working on, this incantation adds (and colors) the branch name to the prompt.
export PS1="[\u@\h\$(if [ -d CVS ]; then if [ -e CVS/Tag ]; then cat CVS/Tag | sed -e 's/^T/ /' | sed -e 's/^N/ /' | sed -e 's/^D/ Date /' | sed -e 's/_BRANCH/\[\033]12;blue\007\]/'; else echo ' \[\033]12;black\007\]MAIN' ; fi; else echo '
\[\033]12;black\007\]' ;fi) \W]\\$ "
(The line breaks are probably messed up)
I did a similar thing for subversion too, but can't find it at the moment.
When I started working on different machines, I'd sometimes forget which OS I was working on. This prompt helped:
UNAME=`uname`
PS1="\[\e[31;1m\]($UNAME)\[\e[37;1m\]\[[\e]2;\h:\u\a\e[0;36m\]\]\h:\[\e[m\e[0;32m\w\e[m]\]\\$ "
for pros only ...
$ export HISTSIZE=10000
$ alias h="history | grep "
$ h some_command
6114 some_command with args
$ !6114
some_command with args
I put up a webpage about some advanced tricks for bash, a while ago.
Check it out.
http://bhaskarvk.info/technology/bash-tricks.html
thanks
I love CDPATH, but I can't see to get tab completion working with it. Any tips?
As far as adding to the conversation, I've always had an alias like this (whether in tcsh, bash, ksh, etc):
alias realias='source ~/.bash_profile'
Javascript Prompt-o-matic
http://www.gilesorr.com/bashprompt/jsb/prompt.html
Recently I came accross this: http://osxdaily.com/2006/12/11/how-to-customize-your-terminal-prompt/ which includes a link in the comments to http://phil.cryer.us/code/dotfiles/bashrc which in turn resulted in my following /etc/bashrc on my PowerBook under OS X 10.4.8 (I think the rest of it originated on one of my Linux boxes...):
# System-wide .bashrc file for interactive bash(1) shells.
# set a fancy prompt (non-color, unless we know we "want" color)
# if [ -n "$PS1" ]; then PS1='\h:\w \u\$ '; fi
# Make bash check it's window size after a process completes
shopt -s checkwinsize
export PATH=$PATH:/usr/X11R6/bin:/opt/local/bin:~/bin
export TERM=xterm-color
##
# DELUXE-USR-LOCAL-BIN-INSERT
# (do not remove this comment)
##
echo $PATH | grep -q -s "/usr/local/bin"
if [ $? -eq 1 ] ; then
PATH=$PATH:/usr/local/bin
export PATH
fi
# Set a fancy prompt (non-color)
case $TERM in
xterm* | aterm | rxvt | screen )
XTITLE="\[\e]0;\u@\h \w\a\]" ;;
* )
XTITLE="" ;;
esac
# if [ -n "$PS1" ]; then PS1="$XTITLE""[\033[01;32m\][\t] [\u@\h] \[\033[01;34m\]\w \$\[\033[00m\] "; fi
# some more ls aliases
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'
##################################################
# Fancy PWD display function
##################################################
# The home directory (HOME) is replaced with a ~
# The last pwdmaxlen characters of the PWD are displayed
# Leading partial directory names are striped off
# /home/me/stuff -> ~/stuff if USER=me
# /usr/share/big_dir_name -> ../share/big_dir_name if pwdmaxlen=20
##################################################
bash_prompt_command() {
# How many characters of the $PWD should be kept
local pwdmaxlen=25
# Indicate that there has been dir truncation
local trunc_symbol=".."
local dir=${PWD##*/}
pwdmaxlen=$(( ( pwdmaxlen < ${#dir} ) ? ${#dir} : pwdmaxlen ))
NEW_PWD=${PWD/$HOME/~}
local pwdoffset=$(( ${#NEW_PWD} - pwdmaxlen ))
if [ ${pwdoffset} -gt "0" ]
then
NEW_PWD=${NEW_PWD:$pwdoffset:$pwdmaxlen}
NEW_PWD=${trunc_symbol}/${NEW_PWD#*/}
fi
}
bash_prompt() {
if [ -n "$PS1" ]; then PS1="$XTITLE""\033[01;32m\][\t] [\u@\h] \[\033[01;34m\]\${NEW_PWD} \\$\[\033[00m\] "; fi
}
export PROMPT_COMMAND=bash_prompt_command
bash_prompt
unset bash_prompt
Thanks for all the comments!
Sean: sorry, it Just Worked for me, I'm afraid, so I'm not sure what to suggest. I have a version of your realias alias, as well!
You can put functions in your .bashrc file too, I have a couple that I use a lot, like this one. It calls debian's apt-cache tool to search for a keyword I give it on the command line. Here is the code snippet I have in .bashrc;
show ()
{
apt-cache search $1
}
And here is how I use it:
$ show cgi
Yeah, this only saves a little typing, but I am lazy. :)
Ahh, well, maybe my issue is I don't have /etc/bash_completion on my machine (OSX 10.4.8). There's a /usr/share/zsh/4.2.3/functions/_bash_completions file, but if I try to source it in bash, I get errors. I'll have to check around. Having tab completion along with CDPATH would be fantastic.
http://bashscripts.org/viewforum.php?f=28
A few alias's dotfiles and alot of tips there. ;)
Wow, thanks a lot for these tricks and shortcuts. very good article.