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 J-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: |