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 M-1. Sample .bashrc file
1 # =============================================================== # 2 # 3 # PERSONAL $HOME/.bashrc FILE for bash-3.0 (or later) 4 # By Emmanuel Rouat [no-email] 5 # 6 # Last modified: Tue Nov 20 22:04:47 CET 2012 7 8 # This file is normally read by interactive shells only. 9 #+ Here is the place to define your aliases, functions and 10 #+ other interactive features like your prompt. 11 # 12 # The majority of the code here assumes you are on a GNU 13 #+ system (most likely a Linux box) and is often based on code 14 #+ found on Usenet or Internet. 15 # 16 # See for instance: 17 # http://tldp.org/LDP/abs/html/index.html 18 # http://www.caliban.org/bash 19 # http://www.shelldorado.com/scripts/categories.html 20 # http://www.dotfiles.org 21 # 22 # The choice of colors was done for a shell with a dark background 23 #+ (white on black), and this is usually also suited for pure text-mode 24 #+ consoles (no X server available). If you use a white background, 25 #+ you'll have to do some other choices for readability. 26 # 27 # This bashrc file is a bit overcrowded. 28 # Remember, it is just just an example. 29 # Tailor it to your needs. 30 # 31 # =============================================================== # 32 33 # --> Comments added by HOWTO author. 34 35 # If not running interactively, don't do anything 36 [ -z "$PS1" ] && return 37 38 39 #------------------------------------------------------------- 40 # Source global definitions (if any) 41 #------------------------------------------------------------- 42 43 44 if [ -f /etc/bashrc ]; then 45 . /etc/bashrc # --> Read /etc/bashrc, if present. 46 fi 47 48 49 #-------------------------------------------------------------- 50 # Automatic setting of $DISPLAY (if not set already). 51 # This works for me - your mileage may vary. . . . 52 # The problem is that different types of terminals give 53 #+ different answers to 'who am i' (rxvt in particular can be 54 #+ troublesome) - however this code seems to work in a majority 55 #+ of cases. 56 #-------------------------------------------------------------- 57 58 function get_xserver () 59 { 60 case $TERM in 61 xterm ) 62 XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' ) 63 # Ane-Pieter Wieringa suggests the following alternative: 64 # I_AM=$(who am i) 65 # SERVER=${I_AM#*(} 66 # SERVER=${SERVER%*)} 67 XSERVER=${XSERVER%%:*} 68 ;; 69 aterm | rxvt) 70 # Find some code that works here. ... 71 ;; 72 esac 73 } 74 75 if [ -z ${DISPLAY:=""} ]; then 76 get_xserver 77 if [[ -z ${XSERVER} || ${XSERVER} == $(hostname) || 78 ${XSERVER} == "unix" ]]; then 79 DISPLAY=":0.0" # Display on local host. 80 else 81 DISPLAY=${XSERVER}:0.0 # Display on remote host. 82 fi 83 fi 84 85 export DISPLAY 86 87 #------------------------------------------------------------- 88 # Some settings 89 #------------------------------------------------------------- 90 91 #set -o nounset # These two options are useful for debugging. 92 #set -o xtrace 93 alias debug="set -o nounset; set -o xtrace" 94 95 ulimit -S -c 0 # Don't want coredumps. 96 set -o notify 97 set -o noclobber 98 set -o ignoreeof 99 100 101 # Enable options: 102 shopt -s cdspell 103 shopt -s cdable_vars 104 shopt -s checkhash 105 shopt -s checkwinsize 106 shopt -s sourcepath 107 shopt -s no_empty_cmd_completion 108 shopt -s cmdhist 109 shopt -s histappend histreedit histverify 110 shopt -s extglob # Necessary for programmable completion. 111 112 # Disable options: 113 shopt -u mailwarn 114 unset MAILCHECK # Don't want my shell to warn me of incoming mail. 115 116 117 #------------------------------------------------------------- 118 # Greeting, motd etc. ... 119 #------------------------------------------------------------- 120 121 # Color definitions (taken from Color Bash Prompt HowTo). 122 # Some colors might look different of some terminals. 123 # For example, I see 'Bold Red' as 'orange' on my screen, 124 # hence the 'Green' 'BRed' 'Red' sequence I often use in my prompt. 125 126 127 # Normal Colors 128 Black='\e[0;30m' # Black 129 Red='\e[0;31m' # Red 130 Green='\e[0;32m' # Green 131 Yellow='\e[0;33m' # Yellow 132 Blue='\e[0;34m' # Blue 133 Purple='\e[0;35m' # Purple 134 Cyan='\e[0;36m' # Cyan 135 White='\e[0;37m' # White 136 137 # Bold 138 BBlack='\e[1;30m' # Black 139 BRed='\e[1;31m' # Red 140 BGreen='\e[1;32m' # Green 141 BYellow='\e[1;33m' # Yellow 142 BBlue='\e[1;34m' # Blue 143 BPurple='\e[1;35m' # Purple 144 BCyan='\e[1;36m' # Cyan 145 BWhite='\e[1;37m' # White 146 147 # Background 148 On_Black='\e[40m' # Black 149 On_Red='\e[41m' # Red 150 On_Green='\e[42m' # Green 151 On_Yellow='\e[43m' # Yellow 152 On_Blue='\e[44m' # Blue 153 On_Purple='\e[45m' # Purple 154 On_Cyan='\e[46m' # Cyan 155 On_White='\e[47m' # White 156 157 NC="\e[m" # Color Reset 158 159 160 ALERT=${BWhite}${On_Red} # Bold White on red background 161 162 163 164 echo -e "${BCyan}This is BASH ${BRed}${BASH_VERSION%.*}${BCyan}\ 165 - DISPLAY on ${BRed}$DISPLAY${NC}\n" 166 date 167 if [ -x /usr/games/fortune ]; then 168 /usr/games/fortune -s # Makes our day a bit more fun.... :-) 169 fi 170 171 function _exit() # Function to run upon exit of shell. 172 { 173 echo -e "${BRed}Hasta la vista, baby${NC}" 174 } 175 trap _exit EXIT 176 177 #------------------------------------------------------------- 178 # Shell Prompt - for many examples, see: 179 # http://www.debian-administration.org/articles/205 180 # http://www.askapache.com/linux/bash-power-prompt.html 181 # http://tldp.org/HOWTO/Bash-Prompt-HOWTO 182 # https://github.com/nojhan/liquidprompt 183 #------------------------------------------------------------- 184 # Current Format: [TIME USER@HOST PWD] > 185 # TIME: 186 # Green == machine load is low 187 # Orange == machine load is medium 188 # Red == machine load is high 189 # ALERT == machine load is very high 190 # USER: 191 # Cyan == normal user 192 # Orange == SU to user 193 # Red == root 194 # HOST: 195 # Cyan == local session 196 # Green == secured remote connection (via ssh) 197 # Red == unsecured remote connection 198 # PWD: 199 # Green == more than 10% free disk space 200 # Orange == less than 10% free disk space 201 # ALERT == less than 5% free disk space 202 # Red == current user does not have write privileges 203 # Cyan == current filesystem is size zero (like /proc) 204 # >: 205 # White == no background or suspended jobs in this shell 206 # Cyan == at least one background job in this shell 207 # Orange == at least one suspended job in this shell 208 # 209 # Command is added to the history file each time you hit enter, 210 # so it's available to all shells (using 'history -a'). 211 212 213 # Test connection type: 214 if [ -n "${SSH_CONNECTION}" ]; then 215 CNX=${Green} # Connected on remote machine, via ssh (good). 216 elif [[ "${DISPLAY%%:0*}" != "" ]]; then 217 CNX=${ALERT} # Connected on remote machine, not via ssh (bad). 218 else 219 CNX=${BCyan} # Connected on local machine. 220 fi 221 222 # Test user type: 223 if [[ ${USER} == "root" ]]; then 224 SU=${Red} # User is root. 225 elif [[ ${USER} != $(logname) ]]; then 226 SU=${BRed} # User is not login user. 227 else 228 SU=${BCyan} # User is normal (well ... most of us are). 229 fi 230 231 232 233 NCPU=$(grep -c 'processor' /proc/cpuinfo) # Number of CPUs 234 SLOAD=$(( 100*${NCPU} )) # Small load 235 MLOAD=$(( 200*${NCPU} )) # Medium load 236 XLOAD=$(( 400*${NCPU} )) # Xlarge load 237 238 # Returns system load as percentage, i.e., '40' rather than '0.40)'. 239 function load() 240 { 241 local SYSLOAD=$(cut -d " " -f1 /proc/loadavg | tr -d '.') 242 # System load of the current host. 243 echo $((10#$SYSLOAD)) # Convert to decimal. 244 } 245 246 # Returns a color indicating system load. 247 function load_color() 248 { 249 local SYSLOAD=$(load) 250 if [ ${SYSLOAD} -gt ${XLOAD} ]; then 251 echo -en ${ALERT} 252 elif [ ${SYSLOAD} -gt ${MLOAD} ]; then 253 echo -en ${Red} 254 elif [ ${SYSLOAD} -gt ${SLOAD} ]; then 255 echo -en ${BRed} 256 else 257 echo -en ${Green} 258 fi 259 } 260 261 # Returns a color according to free disk space in $PWD. 262 function disk_color() 263 { 264 if [ ! -w "${PWD}" ] ; then 265 echo -en ${Red} 266 # No 'write' privilege in the current directory. 267 elif [ -s "${PWD}" ] ; then 268 local used=$(command df -P "$PWD" | 269 awk 'END {print $5} {sub(/%/,"")}') 270 if [ ${used} -gt 95 ]; then 271 echo -en ${ALERT} # Disk almost full (>95%). 272 elif [ ${used} -gt 90 ]; then 273 echo -en ${BRed} # Free disk space almost gone. 274 else 275 echo -en ${Green} # Free disk space is ok. 276 fi 277 else 278 echo -en ${Cyan} 279 # Current directory is size '0' (like /proc, /sys etc). 280 fi 281 } 282 283 # Returns a color according to running/suspended jobs. 284 function job_color() 285 { 286 if [ $(jobs -s | wc -l) -gt "0" ]; then 287 echo -en ${BRed} 288 elif [ $(jobs -r | wc -l) -gt "0" ] ; then 289 echo -en ${BCyan} 290 fi 291 } 292 293 # Adds some text in the terminal frame (if applicable). 294 295 296 # Now we construct the prompt. 297 PROMPT_COMMAND="history -a" 298 case ${TERM} in 299 *term | rxvt | linux) 300 PS1="\[\$(load_color)\][\A\[${NC}\] " 301 # Time of day (with load info): 302 PS1="\[\$(load_color)\][\A\[${NC}\] " 303 # User@Host (with connection type info): 304 PS1=${PS1}"\[${SU}\]\u\[${NC}\]@\[${CNX}\]\h\[${NC}\] " 305 # PWD (with 'disk space' info): 306 PS1=${PS1}"\[\$(disk_color)\]\W]\[${NC}\] " 307 # Prompt (with 'job' info): 308 PS1=${PS1}"\[\$(job_color)\]>\[${NC}\] " 309 # Set title of current xterm: 310 PS1=${PS1}"\[\e]0;[\u@\h] \w\a\]" 311 ;; 312 *) 313 PS1="(\A \u@\h \W) > " # --> PS1="(\A \u@\h \w) > " 314 # --> Shows full pathname of current dir. 315 ;; 316 esac 317 318 319 320 export TIMEFORMAT=$'\nreal %3R\tuser %3U\tsys %3S\tpcpu %P\n' 321 export HISTIGNORE="&:bg:fg:ll:h" 322 export HISTTIMEFORMAT="$(echo -e ${BCyan})[%d/%m %H:%M:%S]$(echo -e ${NC}) " 323 export HISTCONTROL=ignoredups 324 export HOSTFILE=$HOME/.hosts # Put a list of remote hosts in ~/.hosts 325 326 327 #============================================================ 328 # 329 # ALIASES AND FUNCTIONS 330 # 331 # Arguably, some functions defined here are quite big. 332 # If you want to make this file smaller, these functions can 333 #+ be converted into scripts and removed from here. 334 # 335 #============================================================ 336 337 #------------------- 338 # Personnal Aliases 339 #------------------- 340 341 alias rm='rm -i' 342 alias cp='cp -i' 343 alias mv='mv -i' 344 # -> Prevents accidentally clobbering files. 345 alias mkdir='mkdir -p' 346 347 alias h='history' 348 alias j='jobs -l' 349 alias which='type -a' 350 alias ..='cd ..' 351 352 # Pretty-print of some PATH variables: 353 alias path='echo -e ${PATH//:/\\n}' 354 alias libpath='echo -e ${LD_LIBRARY_PATH//:/\\n}' 355 356 357 alias du='du -kh' # Makes a more readable output. 358 alias df='df -kTh' 359 360 #------------------------------------------------------------- 361 # The 'ls' family (this assumes you use a recent GNU ls). 362 #------------------------------------------------------------- 363 # Add colors for filetype and human-readable sizes by default on 'ls': 364 alias ls='ls -h --color' 365 alias lx='ls -lXB' # Sort by extension. 366 alias lk='ls -lSr' # Sort by size, biggest last. 367 alias lt='ls -ltr' # Sort by date, most recent last. 368 alias lc='ls -ltcr' # Sort by/show change time,most recent last. 369 alias lu='ls -ltur' # Sort by/show access time,most recent last. 370 371 # The ubiquitous 'll': directories first, with alphanumeric sorting: 372 alias ll="ls -lv --group-directories-first" 373 alias lm='ll |more' # Pipe through 'more' 374 alias lr='ll -R' # Recursive ls. 375 alias la='ll -A' # Show hidden files. 376 alias tree='tree -Csuh' # Nice alternative to 'recursive ls' ... 377 378 379 #------------------------------------------------------------- 380 # Tailoring 'less' 381 #------------------------------------------------------------- 382 383 alias more='less' 384 export PAGER=less 385 export LESSCHARSET='latin1' 386 export LESSOPEN='|/usr/bin/lesspipe.sh %s 2>&-' 387 # Use this if lesspipe.sh exists. 388 export LESS='-i -N -w -z-4 -g -e -M -X -F -R -P%t?f%f \ 389 :stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...' 390 391 # LESS man page colors (makes Man pages more readable). 392 export LESS_TERMCAP_mb=$'\E[01;31m' 393 export LESS_TERMCAP_md=$'\E[01;31m' 394 export LESS_TERMCAP_me=$'\E[0m' 395 export LESS_TERMCAP_se=$'\E[0m' 396 export LESS_TERMCAP_so=$'\E[01;44;33m' 397 export LESS_TERMCAP_ue=$'\E[0m' 398 export LESS_TERMCAP_us=$'\E[01;32m' 399 400 401 #------------------------------------------------------------- 402 # Spelling typos - highly personnal and keyboard-dependent :-) 403 #------------------------------------------------------------- 404 405 alias xs='cd' 406 alias vf='cd' 407 alias moer='more' 408 alias moew='more' 409 alias kk='ll' 410 411 412 #------------------------------------------------------------- 413 # A few fun ones 414 #------------------------------------------------------------- 415 416 # Adds some text in the terminal frame (if applicable). 417 418 function xtitle() 419 { 420 case "$TERM" in 421 *term* | rxvt) 422 echo -en "\e]0;$*\a" ;; 423 *) ;; 424 esac 425 } 426 427 428 # Aliases that use xtitle 429 alias top='xtitle Processes on $HOST && top' 430 alias make='xtitle Making $(basename $PWD) ; make' 431 432 # .. and functions 433 function man() 434 { 435 for i ; do 436 xtitle The $(basename $1|tr -d .[:digit:]) manual 437 command man -a "$i" 438 done 439 } 440 441 442 #------------------------------------------------------------- 443 # Make the following commands run in background automatically: 444 #------------------------------------------------------------- 445 446 function te() # wrapper around xemacs/gnuserv 447 { 448 if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then 449 gnuclient -q "$@"; 450 else 451 ( xemacs "$@" &); 452 fi 453 } 454 455 function soffice() { command soffice "$@" & } 456 function firefox() { command firefox "$@" & } 457 function xpdf() { command xpdf "$@" & } 458 459 460 #------------------------------------------------------------- 461 # File & strings related functions: 462 #------------------------------------------------------------- 463 464 465 # Find a file with a pattern in name: 466 function ff() { find . -type f -iname '*'"$*"'*' -ls ; } 467 468 # Find a file with pattern $1 in name and Execute $2 on it: 469 function fe() { find . -type f -iname '*'"${1:-}"'*' \ 470 -exec ${2:-file} {} \; ; } 471 472 # Find a pattern in a set of files and highlight them: 473 #+ (needs a recent version of egrep). 474 function fstr() 475 { 476 OPTIND=1 477 local mycase="" 478 local usage="fstr: find string in files. 479 Usage: fstr [-i] \"pattern\" [\"filename pattern\"] " 480 while getopts :it opt 481 do 482 case "$opt" in 483 i) mycase="-i " ;; 484 *) echo "$usage"; return ;; 485 esac 486 done 487 shift $(( $OPTIND - 1 )) 488 if [ "$#" -lt 1 ]; then 489 echo "$usage" 490 return; 491 fi 492 find . -type f -name "${2:-*}" -print0 | \ 493 xargs -0 egrep --color=always -sn ${case} "$1" 2>&- | more 494 495 } 496 497 498 function swap() 499 { # Swap 2 filenames around, if they exist (from Uzi's bashrc). 500 local TMPFILE=tmp.$$ 501 502 [ $# -ne 2 ] && echo "swap: 2 arguments needed" && return 1 503 [ ! -e $1 ] && echo "swap: $1 does not exist" && return 1 504 [ ! -e $2 ] && echo "swap: $2 does not exist" && return 1 505 506 mv "$1" $TMPFILE 507 mv "$2" "$1" 508 mv $TMPFILE "$2" 509 } 510 511 function extract() # Handy Extract Program 512 { 513 if [ -f $1 ] ; then 514 case $1 in 515 *.tar.bz2) tar xvjf $1 ;; 516 *.tar.gz) tar xvzf $1 ;; 517 *.bz2) bunzip2 $1 ;; 518 *.rar) unrar x $1 ;; 519 *.gz) gunzip $1 ;; 520 *.tar) tar xvf $1 ;; 521 *.tbz2) tar xvjf $1 ;; 522 *.tgz) tar xvzf $1 ;; 523 *.zip) unzip $1 ;; 524 *.Z) uncompress $1 ;; 525 *.7z) 7z x $1 ;; 526 *) echo "'$1' cannot be extracted via >extract<" ;; 527 esac 528 else 529 echo "'$1' is not a valid file!" 530 fi 531 } 532 533 534 # Creates an archive (*.tar.gz) from given directory. 535 function maketar() { tar cvzf "${1%%/}.tar.gz" "${1%%/}/"; } 536 537 # Create a ZIP archive of a file or folder. 538 function makezip() { zip -r "${1%%/}.zip" "$1" ; } 539 540 # Make your directories and files access rights sane. 541 function sanitize() { chmod -R u=rwX,g=rX,o= "$@" ;} 542 543 #------------------------------------------------------------- 544 # Process/system related functions: 545 #------------------------------------------------------------- 546 547 548 function my_ps() { ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; } 549 function pp() { my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; } 550 551 552 function killps() # kill by process name 553 { 554 local pid pname sig="-TERM" # default signal 555 if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then 556 echo "Usage: killps [-SIGNAL] pattern" 557 return; 558 fi 559 if [ $# = 2 ]; then sig=$1 ; fi 560 for pid in $(my_ps| awk '!/awk/ && $0~pat { print $1 }' pat=${!#} ) 561 do 562 pname=$(my_ps | awk '$1~var { print $5 }' var=$pid ) 563 if ask "Kill process $pid <$pname> with signal $sig?" 564 then kill $sig $pid 565 fi 566 done 567 } 568 569 function mydf() # Pretty-print of 'df' output. 570 { # Inspired by 'dfc' utility. 571 for fs ; do 572 573 if [ ! -d $fs ] 574 then 575 echo -e $fs" :No such file or directory" ; continue 576 fi 577 578 local info=( $(command df -P $fs | awk 'END{ print $2,$3,$5 }') ) 579 local free=( $(command df -Pkh $fs | awk 'END{ print $4 }') ) 580 local nbstars=$(( 20 * ${info[1]} / ${info[0]} )) 581 local out="[" 582 for ((j=0;j<20;j++)); do 583 if [ ${j} -lt ${nbstars} ]; then 584 out=$out"*" 585 else 586 out=$out"-" 587 fi 588 done 589 out=${info[2]}" "$out"] ("$free" free on "$fs")" 590 echo -e $out 591 done 592 } 593 594 595 function my_ip() # Get IP adress on ethernet. 596 { 597 MY_IP=$(/sbin/ifconfig eth0 | awk '/inet/ { print $2 } ' | 598 sed -e s/addr://) 599 echo ${MY_IP:-"Not connected"} 600 } 601 602 function ii() # Get current host related info. 603 { 604 echo -e "\nYou are logged on ${BRed}$HOST" 605 echo -e "\n${BRed}Additionnal information:$NC " ; uname -a 606 echo -e "\n${BRed}Users logged on:$NC " ; w -hs | 607 cut -d " " -f1 | sort | uniq 608 echo -e "\n${BRed}Current date :$NC " ; date 609 echo -e "\n${BRed}Machine stats :$NC " ; uptime 610 echo -e "\n${BRed}Memory stats :$NC " ; free 611 echo -e "\n${BRed}Diskspace :$NC " ; mydf / $HOME 612 echo -e "\n${BRed}Local IP Address :$NC" ; my_ip 613 echo -e "\n${BRed}Open connections :$NC "; netstat -pan --inet; 614 echo 615 } 616 617 #------------------------------------------------------------- 618 # Misc utilities: 619 #------------------------------------------------------------- 620 621 function repeat() # Repeat n times command. 622 { 623 local i max 624 max=$1; shift; 625 for ((i=1; i <= max ; i++)); do # --> C-like syntax 626 eval "$@"; 627 done 628 } 629 630 631 function ask() # See 'killps' for example of use. 632 { 633 echo -n "$@" '[y/n] ' ; read ans 634 case "$ans" in 635 y*|Y*) return 0 ;; 636 *) return 1 ;; 637 esac 638 } 639 640 function corename() # Get name of app that created a corefile. 641 { 642 for file ; do 643 echo -n $file : ; gdb --core=$file --batch | head -1 644 done 645 } 646 647 648 649 #========================================================================= 650 # 651 # PROGRAMMABLE COMPLETION SECTION 652 # Most are taken from the bash 2.05 documentation and from Ian McDonald's 653 # 'Bash completion' package (http://www.caliban.org/bash/#completion) 654 # You will in fact need bash more recent then 3.0 for some features. 655 # 656 # Note that most linux distributions now provide many completions 657 # 'out of the box' - however, you might need to make your own one day, 658 # so I kept those here as examples. 659 #========================================================================= 660 661 if [ "${BASH_VERSION%.*}" \< "3.0" ]; then 662 echo "You will need to upgrade to version 3.0 for full \ 663 programmable completion features" 664 return 665 fi 666 667 shopt -s extglob # Necessary. 668 669 complete -A hostname rsh rcp telnet rlogin ftp ping disk 670 complete -A export printenv 671 complete -A variable export local readonly unset 672 complete -A enabled builtin 673 complete -A alias alias unalias 674 complete -A function function 675 complete -A user su mail finger 676 677 complete -A helptopic help # Currently same as builtins. 678 complete -A shopt shopt 679 complete -A stopped -P '%' bg 680 complete -A job -P '%' fg jobs disown 681 682 complete -A directory mkdir rmdir 683 complete -A directory -o default cd 684 685 # Compression 686 complete -f -o default -X '*.+(zip|ZIP)' zip 687 complete -f -o default -X '!*.+(zip|ZIP)' unzip 688 complete -f -o default -X '*.+(z|Z)' compress 689 complete -f -o default -X '!*.+(z|Z)' uncompress 690 complete -f -o default -X '*.+(gz|GZ)' gzip 691 complete -f -o default -X '!*.+(gz|GZ)' gunzip 692 complete -f -o default -X '*.+(bz2|BZ2)' bzip2 693 complete -f -o default -X '!*.+(bz2|BZ2)' bunzip2 694 complete -f -o default -X '!*.+(zip|ZIP|z|Z|gz|GZ|bz2|BZ2)' extract 695 696 697 # Documents - Postscript,pdf,dvi..... 698 complete -f -o default -X '!*.+(ps|PS)' gs ghostview ps2pdf ps2ascii 699 complete -f -o default -X \ 700 '!*.+(dvi|DVI)' dvips dvipdf xdvi dviselect dvitype 701 complete -f -o default -X '!*.+(pdf|PDF)' acroread pdf2ps 702 complete -f -o default -X '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?\ 703 (.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv 704 complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf 705 complete -f -o default -X '!*.tex' tex latex slitex 706 complete -f -o default -X '!*.lyx' lyx 707 complete -f -o default -X '!*.+(htm*|HTM*)' lynx html2ps 708 complete -f -o default -X \ 709 '!*.+(doc|DOC|xls|XLS|ppt|PPT|sx?|SX?|csv|CSV|od?|OD?|ott|OTT)' soffice 710 711 # Multimedia 712 complete -f -o default -X \ 713 '!*.+(gif|GIF|jp*g|JP*G|bmp|BMP|xpm|XPM|png|PNG)' xv gimp ee gqview 714 complete -f -o default -X '!*.+(mp3|MP3)' mpg123 mpg321 715 complete -f -o default -X '!*.+(ogg|OGG)' ogg123 716 complete -f -o default -X \ 717 '!*.@(mp[23]|MP[23]|ogg|OGG|wav|WAV|pls|\ 718 m3u|xm|mod|s[3t]m|it|mtm|ult|flac)' xmms 719 complete -f -o default -X '!*.@(mp?(e)g|MP?(E)G|wma|avi|AVI|\ 720 asf|vob|VOB|bin|dat|vcd|ps|pes|fli|viv|rm|ram|yuv|mov|MOV|qt|\ 721 QT|wmv|mp3|MP3|ogg|OGG|ogm|OGM|mp4|MP4|wav|WAV|asx|ASX)' xine 722 723 724 725 complete -f -o default -X '!*.pl' perl perl5 726 727 728 # This is a 'universal' completion function - it works when commands have 729 #+ a so-called 'long options' mode , ie: 'ls --all' instead of 'ls -a' 730 # Needs the '-o' option of grep 731 #+ (try the commented-out version if not available). 732 733 # First, remove '=' from completion word separators 734 #+ (this will allow completions like 'ls --color=auto' to work correctly). 735 736 COMP_WORDBREAKS=${COMP_WORDBREAKS/=/} 737 738 739 _get_longopts() 740 { 741 #$1 --help | sed -e '/--/!d' -e 's/.*--\([^[:space:].,]*\).*/--\1/'| \ 742 #grep ^"$2" |sort -u ; 743 $1 --help | grep -o -e "--[^[:space:].,]*" | grep -e "$2" |sort -u 744 } 745 746 _longopts() 747 { 748 local cur 749 cur=${COMP_WORDS[COMP_CWORD]} 750 751 case "${cur:-*}" in 752 -*) ;; 753 *) return ;; 754 esac 755 756 case "$1" in 757 \~*) eval cmd="$1" ;; 758 *) cmd="$1" ;; 759 esac 760 COMPREPLY=( $(_get_longopts ${1} ${cur} ) ) 761 } 762 complete -o default -F _longopts configure bash 763 complete -o default -F _longopts wget id info a2ps ls recode 764 765 _tar() 766 { 767 local cur ext regex tar untar 768 769 COMPREPLY=() 770 cur=${COMP_WORDS[COMP_CWORD]} 771 772 # If we want an option, return the possible long options. 773 case "$cur" in 774 -*) COMPREPLY=( $(_get_longopts $1 $cur ) ); return 0;; 775 esac 776 777 if [ $COMP_CWORD -eq 1 ]; then 778 COMPREPLY=( $( compgen -W 'c t x u r d A' -- $cur ) ) 779 return 0 780 fi 781 782 case "${COMP_WORDS[1]}" in 783 ?(-)c*f) 784 COMPREPLY=( $( compgen -f $cur ) ) 785 return 0 786 ;; 787 +([^Izjy])f) 788 ext='tar' 789 regex=$ext 790 ;; 791 *z*f) 792 ext='tar.gz' 793 regex='t\(ar\.\)\(gz\|Z\)' 794 ;; 795 *[Ijy]*f) 796 ext='t?(ar.)bz?(2)' 797 regex='t\(ar\.\)bz2\?' 798 ;; 799 *) 800 COMPREPLY=( $( compgen -f $cur ) ) 801 return 0 802 ;; 803 804 esac 805 806 if [[ "$COMP_LINE" == tar*.$ext' '* ]]; then 807 # Complete on files in tar file. 808 # 809 # Get name of tar file from command line. 810 tar=$( echo "$COMP_LINE" | \ 811 sed -e 's|^.* \([^ ]*'$regex'\) .*$|\1|' ) 812 # Devise how to untar and list it. 813 untar=t${COMP_WORDS[1]//[^Izjyf]/} 814 815 COMPREPLY=( $( compgen -W "$( echo $( tar $untar $tar \ 816 2>/dev/null ) )" -- "$cur" ) ) 817 return 0 818 819 else 820 # File completion on relevant files. 821 COMPREPLY=( $( compgen -G $cur\*.$ext ) ) 822 823 fi 824 825 return 0 826 827 } 828 829 complete -F _tar -o default tar 830 831 _make() 832 { 833 local mdef makef makef_dir="." makef_inc gcmd cur prev i; 834 COMPREPLY=(); 835 cur=${COMP_WORDS[COMP_CWORD]}; 836 prev=${COMP_WORDS[COMP_CWORD-1]}; 837 case "$prev" in 838 -*f) 839 COMPREPLY=($(compgen -f $cur )); 840 return 0 841 ;; 842 esac; 843 case "$cur" in 844 -*) 845 COMPREPLY=($(_get_longopts $1 $cur )); 846 return 0 847 ;; 848 esac; 849 850 # ... make reads 851 # GNUmakefile, 852 # then makefile 853 # then Makefile ... 854 if [ -f ${makef_dir}/GNUmakefile ]; then 855 makef=${makef_dir}/GNUmakefile 856 elif [ -f ${makef_dir}/makefile ]; then 857 makef=${makef_dir}/makefile 858 elif [ -f ${makef_dir}/Makefile ]; then 859 makef=${makef_dir}/Makefile 860 else 861 makef=${makef_dir}/*.mk # Local convention. 862 fi 863 864 865 # Before we scan for targets, see if a Makefile name was 866 #+ specified with -f. 867 for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do 868 if [[ ${COMP_WORDS[i]} == -f ]]; then 869 # eval for tilde expansion 870 eval makef=${COMP_WORDS[i+1]} 871 break 872 fi 873 done 874 [ ! -f $makef ] && return 0 875 876 # Deal with included Makefiles. 877 makef_inc=$( grep -E '^-?include' $makef | 878 sed -e "s,^.* ,"$makef_dir"/," ) 879 for file in $makef_inc; do 880 [ -f $file ] && makef="$makef $file" 881 done 882 883 884 # If we have a partial word to complete, restrict completions 885 #+ to matches of that word. 886 if [ -n "$cur" ]; then gcmd='grep "^$cur"' ; else gcmd=cat ; fi 887 888 COMPREPLY=( $( awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \ 889 {split($1,A,/ /);for(i in A)print A[i]}' \ 890 $makef 2>/dev/null | eval $gcmd )) 891 892 } 893 894 complete -F _make -X '+($*|*.[cho])' make gmake pmake 895 896 897 898 899 _killall() 900 { 901 local cur prev 902 COMPREPLY=() 903 cur=${COMP_WORDS[COMP_CWORD]} 904 905 # Get a list of processes 906 #+ (the first sed evaluation 907 #+ takes care of swapped out processes, the second 908 #+ takes care of getting the basename of the process). 909 COMPREPLY=( $( ps -u $USER -o comm | \ 910 sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \ 911 awk '{if ($0 ~ /^'$cur'/) print $0}' )) 912 913 return 0 914 } 915 916 complete -F _killall killall killps 917 918 919 920 # Local Variables: 921 # mode:shell-script 922 # sh-shell:bash 923 # End: |
And, here is a snippet from Andrzej Szelachowski's instructive .bash_profile file.
Example M-2. .bash_profile file
1 # From Andrzej Szelachowski's ~/.bash_profile: 2 3 4 # Note that a variable may require special treatment 5 #+ if it will be exported. 6 7 DARKGRAY='\e[1;30m' 8 LIGHTRED='\e[1;31m' 9 GREEN='\e[32m' 10 YELLOW='\e[1;33m' 11 LIGHTBLUE='\e[1;34m' 12 NC='\e[m' 13 14 PCT="\`if [[ \$EUID -eq 0 ]]; then T='$LIGHTRED' ; else T='$LIGHTBLUE'; fi; 15 echo \$T \`" 16 17 # For "literal" command substitution to be assigned to a variable, 18 #+ use escapes and double quotes: 19 #+ PCT="\` ... \`" . . . 20 # Otherwise, the value of PCT variable is assigned only once, 21 #+ when the variable is exported/read from .bash_profile, 22 #+ and it will not change afterwards even if the user ID changes. 23 24 25 PS1="\n$GREEN[\w] \n$DARKGRAY($PCT\t$DARKGRAY)-($PCT\u$DARKGRAY)-($PCT\! 26 $DARKGRAY)$YELLOW-> $NC" 27 28 # Escape a variables whose value changes: 29 # if [[ \$EUID -eq 0 ]], 30 # Otherwise the value of the EUID variable will be assigned only once, 31 #+ as above. 32 33 # When a variable is assigned, it should be called escaped: 34 #+ echo \$T, 35 # Otherwise the value of the T variable is taken from the moment the PCT 36 #+ variable is exported/read from .bash_profile. 37 # So, in this example it would be null. 38 39 # When a variable's value contains a semicolon it should be strong quoted: 40 # T='$LIGHTRED', 41 # Otherwise, the semicolon will be interpreted as a command separator. 42 43 44 # Variables PCT and PS1 can be merged into a new PS1 variable: 45 46 PS1="\`if [[ \$EUID -eq 0 ]]; then PCT='$LIGHTRED'; 47 else PCT='$LIGHTBLUE'; fi; 48 echo '\n$GREEN[\w] \n$DARKGRAY('\$PCT'\t$DARKGRAY)-\ 49 ('\$PCT'\u$DARKGRAY)-('\$PCT'\!$DARKGRAY)$YELLOW-> $NC'\`" 50 51 # The trick is to use strong quoting for parts of old PS1 variable. |