Appendix K. 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. He welcomes reader feedback on it.

Study the file carefully, and feel free to reuse code snippets and functions from it in your own .bashrc file or even in your scripts.


Example K-1. Sample .bashrc file

   1 #===============================================================
   2 #
   3 # PERSONAL $HOME/.bashrc FILE for bash-2.05a (or later)
   4 #
   5 # Last modified: Tue Apr 15 20:32:34 CEST 2003
   6 #
   7 # This file is read (normally) by interactive shells only.
   8 # Here is the place to define your aliases, functions and
   9 # other interactive features like your prompt.
  10 #
  11 # This file was designed (originally) for Solaris but based 
  12 # on Redhat's default .bashrc file
  13 # --> Modified for Linux.
  14 # The majority of the code you'll find here is based on code found
  15 # on Usenet (or internet).
  16 # This bashrc file is a bit overcrowded - remember it is just
  17 # just an example. Tailor it to your needs
  18 #
  19 #
  20 #===============================================================
  21 
  22 # --> Comments added by HOWTO author.
  23 # --> And then edited again by ER :-)
  24 
  25 #-----------------------------------
  26 # Source global definitions (if any)
  27 #-----------------------------------
  28 
  29 if [ -f /etc/bashrc ]; then
  30         . /etc/bashrc   # --> Read /etc/bashrc, if present.
  31 fi
  32 
  33 #-------------------------------------------------------------
  34 # Automatic setting of $DISPLAY (if not set already)
  35 # This works for linux - your mileage may vary.... 
  36 # The problem is that different types of terminals give
  37 # different answers to 'who am i'......
  38 # I have not found a 'universal' method yet
  39 #-------------------------------------------------------------
  40 
  41 function get_xserver ()
  42 {
  43     case $TERM in
  44 	xterm )
  45             XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' ) 
  46             # Ane-Pieter Wieringa suggests the following alternative:
  47             # I_AM=$(who am i)
  48             # SERVER=${I_AM#*(}
  49             # SERVER=${SERVER%*)}
  50 
  51             XSERVER=${XSERVER%%:*}
  52 	    ;;
  53 	aterm | rxvt)
  54  	# find some code that works here.....
  55 	    ;;
  56     esac  
  57 }
  58 
  59 if [ -z ${DISPLAY:=""} ]; then
  60     get_xserver
  61     if [[ -z ${XSERVER}  || ${XSERVER} == $(hostname) || ${XSERVER} == "unix" ]]; then 
  62 	DISPLAY=":0.0"		# Display on local host
  63     else		
  64 	DISPLAY=${XSERVER}:0.0	# Display on remote host
  65     fi
  66 fi
  67 
  68 export DISPLAY
  69 
  70 #---------------
  71 # Some settings
  72 #---------------
  73 
  74 ulimit -S -c 0		# Don't want any coredumps
  75 set -o notify
  76 set -o noclobber
  77 set -o ignoreeof
  78 set -o nounset
  79 #set -o xtrace          # useful for debuging
  80 
  81 # Enable options:
  82 shopt -s cdspell
  83 shopt -s cdable_vars
  84 shopt -s checkhash
  85 shopt -s checkwinsize
  86 shopt -s mailwarn
  87 shopt -s sourcepath
  88 shopt -s no_empty_cmd_completion  # bash>=2.04 only
  89 shopt -s cmdhist
  90 shopt -s histappend histreedit histverify
  91 shopt -s extglob	# necessary for programmable completion
  92 
  93 # Disable options:
  94 shopt -u mailwarn
  95 unset MAILCHECK		# I don't want my shell to warn me of incoming mail
  96 
  97 
  98 export TIMEFORMAT=$'\nreal %3R\tuser %3U\tsys %3S\tpcpu %P\n'
  99 export HISTIGNORE="&:bg:fg:ll:h"
 100 export HOSTFILE=$HOME/.hosts	# Put a list of remote hosts in ~/.hosts
 101 
 102 
 103 
 104 #-----------------------
 105 # Greeting, motd etc...
 106 #-----------------------
 107 
 108 # Define some colors first:
 109 red='\e[0;31m'
 110 RED='\e[1;31m'
 111 blue='\e[0;34m'
 112 BLUE='\e[1;34m'
 113 cyan='\e[0;36m'
 114 CYAN='\e[1;36m'
 115 NC='\e[0m'              # No Color
 116 # --> Nice. Has the same effect as using "ansi.sys" in DOS.
 117 
 118 # Looks best on a black background.....
 119 echo -e "${CYAN}This is BASH ${RED}${BASH_VERSION%.*}${CYAN} - DISPLAY on ${RED}$DISPLAY${NC}\n"
 120 date
 121 if [ -x /usr/games/fortune ]; then
 122     /usr/games/fortune -s     # makes our day a bit more fun.... :-)
 123 fi
 124 
 125 function _exit()	# function to run upon exit of shell
 126 {
 127     echo -e "${RED}Hasta la vista, baby${NC}"
 128 }
 129 trap _exit EXIT
 130 
 131 #---------------
 132 # Shell Prompt
 133 #---------------
 134 
 135 if [[ "${DISPLAY#$HOST}" != ":0.0" &&  "${DISPLAY}" != ":0" ]]; then  
 136     HILIT=${red}   # remote machine: prompt will be partly red
 137 else
 138     HILIT=${cyan}  # local machine: prompt will be partly cyan
 139 fi
 140 
 141 #  --> Replace instances of \W with \w in prompt functions below
 142 #+ --> to get display of full path name.
 143 
 144 function fastprompt()
 145 {
 146     unset PROMPT_COMMAND
 147     case $TERM in
 148         *term | rxvt )
 149             PS1="${HILIT}[\h]$NC \W > \[\033]0;\${TERM} [\u@\h] \w\007\]" ;;
 150 	linux )
 151 	    PS1="${HILIT}[\h]$NC \W > " ;;
 152         *)
 153             PS1="[\h] \W > " ;;
 154     esac
 155 }
 156 
 157 function powerprompt()
 158 {
 159     _powerprompt()
 160     {
 161         LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")
 162     }
 163 
 164     PROMPT_COMMAND=_powerprompt
 165     case $TERM in
 166         *term | rxvt  )
 167             PS1="${HILIT}[\A \$LOAD]$NC\n[\h \#] \W > \[\033]0;\${TERM} [\u@\h] \w\007\]" ;;
 168         linux )
 169             PS1="${HILIT}[\A - \$LOAD]$NC\n[\h \#] \w > " ;;
 170         * )
 171             PS1="[\A - \$LOAD]\n[\h \#] \w > " ;;
 172     esac
 173 }
 174 
 175 powerprompt     # this is the default prompt - might be slow
 176                 # If too slow, use fastprompt instead....
 177 
 178 #===============================================================
 179 #
 180 # ALIASES AND FUNCTIONS
 181 #
 182 # Arguably, some functions defined here are quite big
 183 # (ie 'lowercase') but my workstation has 512Meg of RAM, so .....
 184 # If you want to make this file smaller, these functions can
 185 # be converted into scripts.
 186 #
 187 # Many functions were taken (almost) straight from the bash-2.04
 188 # examples.
 189 #
 190 #===============================================================
 191 
 192 #-------------------
 193 # Personnal Aliases
 194 #-------------------
 195 
 196 alias rm='rm -i'
 197 alias cp='cp -i'
 198 alias mv='mv -i'
 199 # -> Prevents accidentally clobbering files.
 200 alias mkdir='mkdir -p'
 201 
 202 alias h='history'
 203 alias j='jobs -l'
 204 alias r='rlogin'
 205 alias which='type -all'
 206 alias ..='cd ..'
 207 alias path='echo -e ${PATH//:/\\n}'
 208 alias print='/usr/bin/lp -o nobanner -d $LPDEST'   # Assumes LPDEST is defined
 209 alias pjet='enscript -h -G -fCourier9 -d $LPDEST'  # Pretty-print using enscript
 210 alias background='xv -root -quit -max -rmode 5'    # Put a picture in the background
 211 alias du='du -kh'
 212 alias df='df -kTh'
 213 
 214 # The 'ls' family (this assumes you use the GNU ls)
 215 alias la='ls -Al'               # show hidden files
 216 alias ls='ls -hF --color'	# add colors for filetype recognition
 217 alias lx='ls -lXB'              # sort by extension
 218 alias lk='ls -lSr'              # sort by size
 219 alias lc='ls -lcr'		# sort by change time  
 220 alias lu='ls -lur'		# sort by access time   
 221 alias lr='ls -lR'               # recursive ls
 222 alias lt='ls -ltr'              # sort by date
 223 alias lm='ls -al |more'         # pipe through 'more'
 224 alias tree='tree -Csu'		# nice alternative to 'ls'
 225 
 226 # tailoring 'less'
 227 alias more='less'
 228 export PAGER=less
 229 export LESSCHARSET='latin1'
 230 export LESSOPEN='|/usr/bin/lesspipe.sh %s 2>&-' # Use this if lesspipe.sh exists
 231 export LESS='-i -N -w  -z-4 -g -e -M -X -F -R -P%t?f%f \
 232 :stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...'
 233 
 234 # spelling typos - highly personnal :-)
 235 alias xs='cd'
 236 alias vf='cd'
 237 alias moer='more'
 238 alias moew='more'
 239 alias kk='ll'
 240 
 241 #----------------
 242 # a few fun ones
 243 #----------------
 244 
 245 function xtitle ()
 246 {
 247     case "$TERM" in
 248         *term | rxvt)
 249             echo -n -e "\033]0;$*\007" ;;
 250         *)  
 251 	    ;;
 252     esac
 253 }
 254 
 255 # aliases...
 256 alias top='xtitle Processes on $HOST && top'
 257 alias make='xtitle Making $(basename $PWD) ; make'
 258 alias ncftp="xtitle ncFTP ; ncftp"
 259 
 260 # .. and functions
 261 function man ()
 262 {
 263     for i ; do
 264 	xtitle The $(basename $1|tr -d .[:digit:]) manual
 265 	command man -F -a "$i"
 266     done
 267 }
 268 
 269 function ll(){ ls -l "$@"| egrep "^d" ; ls -lXB "$@" 2>&-| egrep -v "^d|total "; }
 270 function te()  # wrapper around xemacs/gnuserv
 271 {
 272     if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then
 273         gnuclient -q "$@";
 274     else
 275         ( xemacs "$@" &);
 276     fi
 277 }
 278 
 279 #-----------------------------------
 280 # File & strings related functions:
 281 #-----------------------------------
 282 
 283 # Find a file with a pattern in name:
 284 function ff() { find . -type f -iname '*'$*'*' -ls ; }
 285 # Find a file with pattern $1 in name and Execute $2 on it:
 286 function fe() { find . -type f -iname '*'$1'*' -exec "${2:-file}" {} \;  ; }
 287 # find pattern in a set of filesand highlight them:
 288 function fstr()
 289 {
 290     OPTIND=1
 291     local case=""
 292     local usage="fstr: find string in files.
 293 Usage: fstr [-i] \"pattern\" [\"filename pattern\"] "
 294     while getopts :it opt
 295     do
 296         case "$opt" in
 297         i) case="-i " ;;
 298         *) echo "$usage"; return;;
 299         esac
 300     done
 301     shift $(( $OPTIND - 1 ))
 302     if [ "$#" -lt 1 ]; then
 303         echo "$usage"
 304         return;
 305     fi
 306     local SMSO=$(tput smso)
 307     local RMSO=$(tput rmso)
 308     find . -type f -name "${2:-*}" -print0 | xargs -0 grep -sn ${case} "$1" 2>&- | \
 309 sed "s/$1/${SMSO}\0${RMSO}/gI" | more
 310 }
 311 
 312 function cuttail() # cut last n lines in file, 10 by default
 313 {
 314     nlines=${2:-10}
 315     sed -n -e :a -e "1,${nlines}!{P;N;D;};N;ba" $1
 316 }
 317 
 318 function lowercase()  # move filenames to lowercase
 319 {
 320     for file ; do
 321         filename=${file##*/}
 322         case "$filename" in
 323         */*) dirname==${file%/*} ;;
 324         *) dirname=.;;
 325         esac
 326         nf=$(echo $filename | tr A-Z a-z)
 327         newname="${dirname}/${nf}"
 328         if [ "$nf" != "$filename" ]; then
 329             mv "$file" "$newname"
 330             echo "lowercase: $file --> $newname"
 331         else
 332             echo "lowercase: $file not changed."
 333         fi
 334     done
 335 }
 336 
 337 function swap()         # swap 2 filenames around
 338 {
 339     local TMPFILE=tmp.$$
 340     mv "$1" $TMPFILE
 341     mv "$2" "$1"
 342     mv $TMPFILE "$2"
 343 }
 344 
 345 
 346 #-----------------------------------
 347 # Process/system related functions:
 348 #-----------------------------------
 349 
 350 function my_ps() { ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; }
 351 function pp() { my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; }
 352 
 353 # This function is roughly the same as 'killall' on linux
 354 # but has no equivalent (that I know of) on Solaris
 355 function killps()   # kill by process name
 356 {
 357     local pid pname sig="-TERM"   # default signal
 358     if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
 359         echo "Usage: killps [-SIGNAL] pattern"
 360         return;
 361     fi
 362     if [ $# = 2 ]; then sig=$1 ; fi
 363     for pid in $(my_ps| awk '!/awk/ && $0~pat { print $1 }' pat=${!#} ) ; do
 364         pname=$(my_ps | awk '$1~var { print $5 }' var=$pid )
 365         if ask "Kill process $pid <$pname> with signal $sig?"
 366             then kill $sig $pid
 367         fi
 368     done
 369 }
 370 
 371 function my_ip() # get IP adresses
 372 {
 373     MY_IP=$(/sbin/ifconfig ppp0 | awk '/inet/ { print $2 } ' | sed -e s/addr://)
 374     MY_ISP=$(/sbin/ifconfig ppp0 | awk '/P-t-P/ { print $3 } ' | sed -e s/P-t-P://)
 375 }
 376 
 377 function ii()   # get current host related info
 378 {
 379     echo -e "\nYou are logged on ${RED}$HOST"
 380     echo -e "\nAdditionnal information:$NC " ; uname -a
 381     echo -e "\n${RED}Users logged on:$NC " ; w -h
 382     echo -e "\n${RED}Current date :$NC " ; date
 383     echo -e "\n${RED}Machine stats :$NC " ; uptime
 384     echo -e "\n${RED}Memory stats :$NC " ; free
 385     my_ip 2>&- ;
 386     echo -e "\n${RED}Local IP Address :$NC" ; echo ${MY_IP:-"Not connected"}
 387     echo -e "\n${RED}ISP Address :$NC" ; echo ${MY_ISP:-"Not connected"}
 388     echo
 389 }
 390 
 391 # Misc utilities:
 392 
 393 function repeat()       # repeat n times command
 394 {
 395     local i max
 396     max=$1; shift;
 397     for ((i=1; i <= max ; i++)); do  # --> C-like syntax
 398         eval "$@";
 399     done
 400 }
 401 
 402 function ask()
 403 {
 404     echo -n "$@" '[y/n] ' ; read ans
 405     case "$ans" in
 406         y*|Y*) return 0 ;;
 407         *) return 1 ;;
 408     esac
 409 }
 410 
 411 #=========================================================================
 412 #
 413 # PROGRAMMABLE COMPLETION - ONLY SINCE BASH-2.04
 414 # Most are taken from the bash 2.05 documentation and from Ian McDonalds
 415 # 'Bash completion' package (http://www.caliban.org/bash/index.shtml#completion)
 416 # You will in fact need bash-2.05a for some features
 417 #
 418 #=========================================================================
 419 
 420 if [ "${BASH_VERSION%.*}" \< "2.05" ]; then
 421     echo "You will need to upgrade to version 2.05 for programmable completion"
 422     return
 423 fi
 424 
 425 shopt -s extglob        # necessary
 426 set +o nounset          # otherwise some completions will fail
 427 
 428 complete -A hostname   rsh rcp telnet rlogin r ftp ping disk
 429 complete -A export     printenv
 430 complete -A variable   export local readonly unset
 431 complete -A enabled    builtin
 432 complete -A alias      alias unalias
 433 complete -A function   function
 434 complete -A user       su mail finger
 435 
 436 complete -A helptopic  help     # currently same as builtins
 437 complete -A shopt      shopt
 438 complete -A stopped -P '%' bg
 439 complete -A job -P '%'     fg jobs disown
 440 
 441 complete -A directory  mkdir rmdir
 442 complete -A directory   -o default cd
 443 
 444 # Compression
 445 complete -f -o default -X '*.+(zip|ZIP)'  zip
 446 complete -f -o default -X '!*.+(zip|ZIP)' unzip
 447 complete -f -o default -X '*.+(z|Z)'      compress
 448 complete -f -o default -X '!*.+(z|Z)'     uncompress
 449 complete -f -o default -X '*.+(gz|GZ)'    gzip
 450 complete -f -o default -X '!*.+(gz|GZ)'   gunzip
 451 complete -f -o default -X '*.+(bz2|BZ2)'  bzip2
 452 complete -f -o default -X '!*.+(bz2|BZ2)' bunzip2
 453 # Postscript,pdf,dvi.....
 454 complete -f -o default -X '!*.ps'  gs ghostview ps2pdf ps2ascii
 455 complete -f -o default -X '!*.dvi' dvips dvipdf xdvi dviselect dvitype
 456 complete -f -o default -X '!*.pdf' acroread pdf2ps
 457 complete -f -o default -X '!*.+(pdf|ps)' gv
 458 complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf
 459 complete -f -o default -X '!*.tex' tex latex slitex
 460 complete -f -o default -X '!*.lyx' lyx
 461 complete -f -o default -X '!*.+(htm*|HTM*)' lynx html2ps
 462 # Multimedia
 463 complete -f -o default -X '!*.+(jp*g|gif|xpm|png|bmp)' xv gimp
 464 complete -f -o default -X '!*.+(mp3|MP3)' mpg123 mpg321
 465 complete -f -o default -X '!*.+(ogg|OGG)' ogg123
 466 
 467 
 468 
 469 complete -f -o default -X '!*.pl'  perl perl5
 470 
 471 # This is a 'universal' completion function - it works when commands have
 472 # a so-called 'long options' mode , ie: 'ls --all' instead of 'ls -a'
 473 
 474 _get_longopts () 
 475 { 
 476     $1 --help | sed  -e '/--/!d' -e 's/.*--\([^[:space:].,]*\).*/--\1/'| \
 477 grep ^"$2" |sort -u ;
 478 }
 479 
 480 _longopts_func ()
 481 {
 482     case "${2:-*}" in
 483 	-*)	;;
 484 	*)	return ;;
 485     esac
 486 
 487     case "$1" in
 488 	\~*)	eval cmd="$1" ;;
 489 	*)	cmd="$1" ;;
 490     esac
 491     COMPREPLY=( $(_get_longopts ${1} ${2} ) )
 492 }
 493 complete  -o default -F _longopts_func configure bash
 494 complete  -o default -F _longopts_func wget id info a2ps ls recode
 495 
 496 
 497 _make_targets ()
 498 {
 499     local mdef makef gcmd cur prev i
 500 
 501     COMPREPLY=()
 502     cur=${COMP_WORDS[COMP_CWORD]}
 503     prev=${COMP_WORDS[COMP_CWORD-1]}
 504 
 505     # if prev argument is -f, return possible filename completions.
 506     # we could be a little smarter here and return matches against
 507     # `makefile Makefile *.mk', whatever exists
 508     case "$prev" in
 509         -*f)    COMPREPLY=( $(compgen -f $cur ) ); return 0;;
 510     esac
 511 
 512     # if we want an option, return the possible posix options
 513     case "$cur" in
 514         -)      COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;;
 515     esac
 516 
 517     # make reads `makefile' before `Makefile'
 518     if [ -f makefile ]; then
 519         mdef=makefile
 520     elif [ -f Makefile ]; then
 521         mdef=Makefile
 522     else
 523         mdef=*.mk               # local convention
 524     fi
 525 
 526     # before we scan for targets, see if a makefile name was specified
 527     # with -f
 528     for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do
 529         if [[ ${COMP_WORDS[i]} == -*f ]]; then
 530             eval makef=${COMP_WORDS[i+1]}       # eval for tilde expansion
 531             break
 532         fi
 533     done
 534 
 535         [ -z "$makef" ] && makef=$mdef
 536 
 537     # if we have a partial word to complete, restrict completions to
 538     # matches of that word
 539     if [ -n "$2" ]; then gcmd='grep "^$2"' ; else gcmd=cat ; fi
 540 
 541     # if we don't want to use *.mk, we can take out the cat and use
 542     # test -f $makef and input redirection
 543     COMPREPLY=( $(cat $makef 2>/dev/null | awk 'BEGIN {FS=":"} /^[^.#   ][^=]*:/ {print $1}' | tr -s ' ' '\012' | sort -u | eval $gcmd ) )
 544 }
 545 
 546 complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake
 547 
 548 
 549 # cvs(1) completion
 550 _cvs ()
 551 {
 552     local cur prev
 553     COMPREPLY=()
 554     cur=${COMP_WORDS[COMP_CWORD]}
 555     prev=${COMP_WORDS[COMP_CWORD-1]}
 556 
 557     if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then
 558         COMPREPLY=( $( compgen -W 'add admin checkout commit diff \
 559         export history import log rdiff release remove rtag status \
 560         tag update' $cur ))
 561     else
 562         COMPREPLY=( $( compgen -f $cur ))
 563     fi
 564     return 0
 565 }
 566 complete -F _cvs cvs
 567 
 568 _killall ()
 569 {
 570     local cur prev
 571     COMPREPLY=()
 572     cur=${COMP_WORDS[COMP_CWORD]}
 573 
 574     # get a list of processes (the first sed evaluation
 575     # takes care of swapped out processes, the second
 576     # takes care of getting the basename of the process)
 577     COMPREPLY=( $( /usr/bin/ps -u $USER -o comm  | \
 578         sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \
 579         awk '{if ($0 ~ /^'$cur'/) print $0}' ))
 580 
 581     return 0
 582 }
 583 
 584 complete -F _killall killall killps
 585 
 586 
 587 # A meta-command completion function for commands like sudo(8), which need to
 588 # first complete on a command, then complete according to that command's own
 589 # completion definition - currently not quite foolproof (e.g. mount and umount
 590 # don't work properly), but still quite useful - By Ian McDonald, modified by me.
 591 
 592 _my_command()
 593 {
 594     local cur func cline cspec
 595     
 596     COMPREPLY=()
 597     cur=${COMP_WORDS[COMP_CWORD]}
 598 
 599     if [ $COMP_CWORD = 1 ]; then
 600 	COMPREPLY=( $( compgen -c $cur ) )
 601     elif complete -p ${COMP_WORDS[1]} &>/dev/null; then
 602 	cspec=$( complete -p ${COMP_WORDS[1]} )
 603 	if [ "${cspec%%-F *}" != "${cspec}" ]; then
 604 	    # complete -F <function>
 605 	    #
 606 	    # COMP_CWORD and COMP_WORDS() are not read-only,
 607 	    # so we can set them before handing off to regular
 608 	    # completion routine
 609 	
 610 	    # set current token number to 1 less than now
 611 	    COMP_CWORD=$(( $COMP_CWORD - 1 ))
 612 	    # get function name
 613 	    func=${cspec#*-F }
 614 	    func=${func%% *}
 615 	    # get current command line minus initial command
 616 	    cline="${COMP_LINE#$1 }"
 617 	    # split current command line tokens into array
 618 		COMP_WORDS=( $cline )
 619 	    $func $cline
 620 	elif [ "${cspec#*-[abcdefgjkvu]}" != "" ]; then
 621 	    # complete -[abcdefgjkvu]
 622 	    #func=$( echo $cspec | sed -e 's/^.*\(-[abcdefgjkvu]\).*$/\1/' )
 623 	    func=$( echo $cspec | sed -e 's/^complete//' -e 's/[^ ]*$//' )
 624 	    COMPREPLY=( $( eval compgen $func $cur ) )
 625 	elif [ "${cspec#*-A}" != "$cspec" ]; then
 626 	    # complete -A <type>
 627 	    func=${cspec#*-A }
 628 	func=${func%% *}
 629 	COMPREPLY=( $( compgen -A $func $cur ) )
 630 	fi
 631     else
 632 	COMPREPLY=( $( compgen -f $cur ) )
 633     fi
 634 }
 635 
 636 
 637 complete -o default -F _my_command nohup exec eval trace truss strace sotruss gdb
 638 complete -o default -F _my_command command type which man nice
 639 
 640 # Local Variables:
 641 # mode:shell-script
 642 # sh-shell:bash
 643 # End: