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