Appendix F. A Sample .bashrc File

The ~/.bashrc file determines the behavior of interactive shells. A good look at this file can lead to a better understanding of Bash.

Emmanuel Rouat contributed the following very elaborate .bashrc file, written for a Linux system. Study this file carefully, and feel free to reuse code snippets and functions from it in your own .bashrc file and even in your scripts.


Example F-1. Sample .bashrc file

   1 #===============================================================
   2 #
   3 # PERSONAL $HOME/.bashrc FILE for bash-2.04 (or later) 
   4 #
   5 # This file is read (normally) by interactive shells only.
   6 # Here is the place to define your aliases, functions and
   7 # other interactive features like your prompt.
   8 # 
   9 # This file was designed (originally) for Solaris.
  10 # --> Modified for Linux.
  11 #
  12 #===============================================================
  13 
  14 # --> Comments added by HOWTO author.
  15 
  16 
  17 #-----------------------------------
  18 # Source global definitions (if any)
  19 #-----------------------------------
  20 
  21 if [ -f /etc/bashrc ]; then
  22 	. /etc/bashrc   # --> Read /etc/bashrc, if present.
  23 fi
  24 
  25 
  26 #-------------------------------------------------------------
  27 # Automatic setting of $DISPLAY (if not set already)
  28 # This works for linux and solaris - your mileage may vary....
  29 #-------------------------------------------------------------
  30 
  31 
  32 if [ -z ${DISPLAY:=""} ]; then
  33     DISPLAY=$(who am i)
  34     DISPLAY=${DISPLAY%%\!*}
  35     if [ -n "$DISPLAY" ]; then
  36 	export DISPLAY=$DISPLAY:0.0
  37     else
  38 	export DISPLAY=":0.0"  # fallback    
  39     fi
  40 fi
  41 
  42 
  43 #---------------
  44 # Some settings
  45 #---------------
  46 
  47 set -o notify
  48 set -o noclobber
  49 set -o ignoreeof
  50 set -o nounset
  51 #set -o xtrace		# useful for debuging 
  52 
  53 shopt -s cdspell 
  54 shopt -s cdable_vars
  55 shopt -s checkhash 
  56 shopt -s checkwinsize 
  57 shopt -s mailwarn
  58 shopt -s sourcepath
  59 shopt -s no_empty_cmd_completion
  60 shopt -s histappend histreedit
  61 shopt -s extglob	# useful for programmable completion
  62 
  63 
  64 
  65 #-----------------------
  66 # Greeting, motd etc...
  67 #-----------------------
  68 
  69 # Define some colors first:
  70 red='\e[0;31m'
  71 RED='\e[1;31m'
  72 blue='\e[0;34m'
  73 BLUE='\e[1;34m'
  74 cyan='\e[0;36m'
  75 CYAN='\e[1;36m'
  76 NC='\e[0m'		# No Color
  77 # --> Nice. Has the same effect as using "ansi.sys" in DOS.
  78 
  79 # Looks best on a black background.....
  80 echo -e "${CYAN}This is BASH ${RED}${BASH_VERSION%.*}${CYAN} - DISPLAY on ${RED}$DISPLAY${NC}\n"
  81 date
  82 
  83 
  84 function _exit()	# function to run upon exit of shell
  85 {
  86     echo -e "${RED}Hasta la vista, baby${NC}"
  87 }
  88 trap _exit 0
  89 
  90 #---------------
  91 # Shell prompt
  92 #---------------
  93 
  94 
  95 function fastprompt()
  96 {
  97     unset PROMPT_COMMAND
  98     case $TERM in
  99 	*term | rxvt )	
 100 	    PS1="[\h] \W > \[\033]0;[\u@\h] \w\007\]" ;;
 101 	*) 
 102 	    PS1="[\h] \W > " ;;
 103     esac
 104 }
 105 
 106 
 107 function powerprompt()
 108 {
 109     _powerprompt() 
 110     { 
 111 	LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")	
 112 	TIME=$(date +%H:%M)
 113     } 
 114   
 115     PROMPT_COMMAND=_powerprompt
 116     case $TERM in
 117 	*term | rxvt  )
 118 	    PS1="${cyan}[\$TIME \$LOAD]$NC\n[\h \#] \W > \[\033]0;[\u@\h] \w\007\]" ;;
 119 	linux )
 120 	    PS1="${cyan}[\$TIME - \$LOAD]$NC\n[\h \#] \w > " ;;
 121 	* )
 122 	    PS1="[\$TIME - \$LOAD]\n[\h \#] \w > " ;;
 123     esac
 124 }
 125 
 126 powerprompt	# this is the default prompt - might be slow
 127 		# If too slow, use fastprompt instead....
 128 
 129 
 130 
 131 #===============================================================
 132 #
 133 # ALIASES AND FUNCTIONS 
 134 #
 135 # Arguably, some functions defined here are quite big 
 136 # (ie 'lowercase') but my workstation has 512Meg of RAM, so .....
 137 # If you want to make this file smaller, these functions can
 138 # be converted into scripts.
 139 # 
 140 # Many functions were taken (almost) straight from the bash-2.04
 141 # examples.
 142 #
 143 #===============================================================
 144 
 145 #-------------------
 146 # Personnal Aliases
 147 #-------------------
 148 
 149 alias rm='rm -i'
 150 alias cp='cp -i'
 151 alias mv='mv -i'
 152 # -> Prevents accidentally clobbering files.
 153 
 154 alias h='history'
 155 alias j='jobs -l'
 156 alias r='rlogin'
 157 alias which='type -a'
 158 alias ..='cd ..'
 159 alias path='echo -e ${PATH//:/\\n}'
 160 alias print='/usr/bin/lp -o nobanner -d $LPDEST'
 161 alias pjet='enscript -h -G -fCourier9 -d $LPDEST '
 162 alias vi='vim'
 163 alias du='du -h'
 164 alias df='df -kh'
 165 
 166 alias ls='ls -hF --color'
 167 alias lx='ls -lXB'
 168 alias lk='ls -lSr'
 169 alias la='ls -Al'
 170 alias lr='ls -lR'
 171 alias lt='ls -ltr'  
 172 alias lm='ls -al |more'
 173 
 174 alias background='xv -root -quit -max -rmode 5'
 175 
 176 alias more='less'
 177 export PAGER=less
 178 export LESSCHARSET='latin1'
 179 export LESSOPEN='|lesspipe.sh %s'  # Use this if lesspipe.sh exists 
 180 export LESS='-i -N -w  -z-4 -g -e -M -X -F -R -P%t?f%f \
 181 :stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...'
 182 
 183 # spelling typos
 184 
 185 alias xs='cd'
 186 alias vf='cd'
 187 alias moer='more'
 188 alias moew='more'
 189 alias kk='ll'
 190 
 191 
 192 
 193 
 194 
 195 #----------------
 196 # a few fun ones
 197 #----------------
 198 
 199 function xtitle () 
 200 { 
 201     case $TERM in
 202 	*term | rxvt) 
 203 	    echo -n -e "\033]0;$*\007" ;;
 204 	*)  ;;
 205     esac
 206 }
 207 
 208 alias top='xtitle Processes on $HOST && top'
 209 alias make='xtitle Making $(basename $PWD) ; make'
 210 alias ncftp="xtitle ncFTP ; ncftp"
 211 
 212 
 213 #---------------
 214 # and functions
 215 #---------------
 216 
 217 function man ()
 218 {
 219     xtitle The $(basename $1|tr -d .[:digit:]) manual
 220     man -a "$*"
 221 }
 222 
 223 
 224 
 225 function ll(){ ls -l  $*| egrep "^d" ; ls -lh  $* 2>&-| egrep -v "^d|total "; }
 226 function xemacs() { { command xemacs -private $* 2>&- & } && disown ;}
 227 function te()  # wrapper around xemacs/gnuserv
 228 {
 229     if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then
 230 	gnuclient -q $@;
 231     else
 232 	( xemacs $@ & );
 233     fi
 234 }
 235 
 236 
 237 #-----------------------------------
 238 # File & strings related functions:
 239 #-----------------------------------
 240 
 241 function ff() { find . -name '*'$1'*' ; }
 242 function fe() { find . -name '*'$1'*' -exec $2 {} \; ; }
 243 function fstr() # find a string in a set of files
 244 {
 245     if [ "$#" -gt 2 ]; then
 246         echo "Usage: fstr \"pattern\" [files] "
 247 	return;
 248     fi
 249     SMSO=$(tput smso)
 250     RMSO=$(tput rmso)
 251     find . -type f -name "${2:-*}" -print | xargs grep -sin "$1" | \
 252 sed "s/$1/$SMSO$1$RMSO/gI"
 253 }
 254 function cuttail() # cut last n lines in file, 10 by default
 255 {
 256     nlines=${2:-10}
 257     sed -n -e :a -e "1,${nlines}!{P;N;D;};N;ba" $1 
 258 }
 259 
 260 function lowercase()  # move filenames to lowercase
 261 {
 262     for file ; do
 263         filename=${file##*/}
 264         case "$filename" in
 265         */*) dirname==${file%/*} ;;
 266         *) dirname=.;;
 267         esac
 268         nf=$(echo $filename | tr A-Z a-z)
 269         newname="${dirname}/${nf}"
 270         if [ "$nf" != "$filename" ]; then
 271             mv "$file" "$newname"
 272             echo "lowercase: $file --> $newname"
 273         else
 274             echo "lowercase: $file not changed."
 275         fi
 276     done
 277 }
 278 
 279 function swap()		# swap 2 filenames around
 280 {
 281     local TMPFILE=tmp.$$
 282     mv $1 $TMPFILE
 283     mv $2 $1
 284     mv $TMPFILE $2
 285 }
 286 
 287 
 288 
 289 # Misc utilities:
 290 
 291 function repeat()	# repeat n times command
 292 {
 293     local i max
 294     max=$1; shift;
 295     for ((i=1; i <= max ; i++)); do  # --> C-like syntax
 296 	eval "$@";
 297     done
 298 }
 299 	
 300 
 301 function ask()
 302 {
 303     echo -n "$@" '[y/n] ' ; read ans
 304     case "$ans" in
 305         y*|Y*) return 0 ;;
 306         *) return 1 ;;
 307     esac
 308 }
 309 
 310 
 311 
 312 #=========================================================================
 313 #
 314 # PROGRAMMABLE COMPLETION - ONLY IN BASH-2.04
 315 # (Most are taken from the bash 2.04 documentation)
 316 #
 317 #=========================================================================
 318 
 319 if [ "${BASH_VERSION%.*}" \< "2.04" ]; then
 320     echo "No programmable completion available"
 321     return
 322 fi
 323    
 324 shopt -s extglob	# necessary
 325 
 326 complete -A hostname   rsh rcp telnet rlogin r ftp ping disk
 327 complete -A command    nohup exec eval trace gdb
 328 complete -A command    command type which 
 329 complete -A export     printenv
 330 complete -A variable   export local readonly unset
 331 complete -A enabled    builtin
 332 complete -A alias      alias unalias
 333 complete -A function   function
 334 complete -A user       su mail finger
 335 
 336 complete -A helptopic  help	# currently same as builtins
 337 complete -A shopt      shopt
 338 complete -A stopped -P '%' bg
 339 complete -A job -P '%'     fg jobs disown
 340 
 341 complete -A directory  mkdir rmdir
 342 
 343 complete -f -X '*.gz'   gzip
 344 complete -f -X '!*.ps'  gs ghostview gv
 345 complete -f -X '!*.pdf' acroread
 346 complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|bmp)' xv gimp
 347 
 348  
 349 _make_targets ()
 350 {
 351     local mdef makef gcmd cur prev i
 352 
 353     COMPREPLY=()
 354     cur=${COMP_WORDS[COMP_CWORD]}
 355     prev=${COMP_WORDS[COMP_CWORD-1]}
 356 
 357     # if prev argument is -f, return possible filename completions.
 358     # we could be a little smarter here and return matches against
 359     # `makefile Makefile *.mk', whatever exists
 360     case "$prev" in
 361 	-*f)	COMPREPLY=( $(compgen -f $cur ) ); return 0;;
 362     esac
 363 
 364     # if we want an option, return the possible posix options
 365     case "$cur" in
 366 	-)	COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;;
 367     esac
 368 
 369     # make reads `makefile' before `Makefile'
 370     if [ -f makefile ]; then
 371 	mdef=makefile
 372     elif [ -f Makefile ]; then
 373 	mdef=Makefile
 374     else
 375 	mdef=*.mk		# local convention
 376     fi
 377 
 378     # before we scan for targets, see if a makefile name was specified
 379     # with -f
 380     for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do
 381 	if [[ ${COMP_WORDS[i]} == -*f ]]; then
 382 	    eval makef=${COMP_WORDS[i+1]}	# eval for tilde expansion
 383 	    break
 384 	fi
 385     done
 386 
 387 	[ -z "$makef" ] && makef=$mdef
 388 
 389     # if we have a partial word to complete, restrict completions to
 390     # matches of that word
 391     if [ -n "$2" ]; then gcmd='grep "^$2"' ; else gcmd=cat ; fi
 392 
 393     # if we don't want to use *.mk, we can take out the cat and use
 394     # test -f $makef and input redirection	
 395     COMPREPLY=( $(cat $makef 2>/dev/null | awk 'BEGIN {FS=":"} /^[^.# 	][^=]*:/ {print $1}' | tr -s ' ' '\012' | sort -u | eval $gcmd ) )
 396 }
 397 
 398 complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake
 399 
 400 
 401 _configure_func ()
 402 {
 403     case "$2" in
 404 	-*)	;;
 405 	*)	return ;;
 406     esac
 407 
 408     case "$1" in
 409 	\~*)	eval cmd=$1 ;;
 410 	*)	cmd="$1" ;;
 411     esac
 412 
 413     COMPREPLY=( $("$cmd" --help | awk '{if ($1 ~ /--.*/) print $1}' | grep ^"$2" | sort -u) )
 414 }
 415 
 416 complete -F _configure_func configure
 417 
 418 _killall ()
 419 {
 420     local cur prev
 421     COMPREPLY=()
 422     cur=${COMP_WORDS[COMP_CWORD]}
 423 
 424     # get a list of processes (the first sed evaluation
 425     # takes care of swapped out processes, the second
 426     # takes care of getting the basename of the process)
 427     COMPREPLY=( $( /usr/bin/ps -u $USER -o comm  | \
 428 	sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \
 429 	awk '{if ($0 ~ /^'$cur'/) print $0}' ))
 430 
 431     return 0
 432 }
 433  
 434 complete -F _killall killall
 435 
 436 
 437 # Local Variables:
 438 # mode:shell-script
 439 # sh-shell:bash
 440 # End: