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