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.05 (or later)
4 #
5 # This file is read (normally) by interactive shells only.
6 # Here is the place to define your aliases, functions and
7 # other interactive features like your prompt.
8 #
9 # This file was designed (originally) for Solaris.
10 # --> Modified for Linux.
11 # This bashrc file is a bit overcrowded - remember it is just
12 # just an example. Tailor it to your needs
13 #
14 #===============================================================
15
16 # --> Comments added by HOWTO author.
17
18 #-----------------------------------
19 # Source global definitions (if any)
20 #-----------------------------------
21
22 if [ -f /etc/bashrc ]; then
23 . /etc/bashrc # --> Read /etc/bashrc, if present.
24 fi
25
26 #-------------------------------------------------------------
27 # Automatic setting of $DISPLAY (if not set already)
28 # This works for linux and solaris - your mileage may vary....
29 #-------------------------------------------------------------
30
31 if [ -z ${DISPLAY:=""} ]; then
32 DISPLAY=$(who am i)
33 DISPLAY=${DISPLAY%%\!*}
34 if [ -n "$DISPLAY" ]; then
35 export DISPLAY=$DISPLAY:0.0
36 else
37 export DISPLAY=":0.0" # fallback
38 fi
39 fi
40
41 #---------------
42 # Some settings
43 #---------------
44
45 set -o notify
46 set -o noclobber
47 set -o ignoreeof
48 set -o nounset
49 #set -o xtrace # useful for debuging
50
51 shopt -s cdspell
52 shopt -s cdable_vars
53 shopt -s checkhash
54 shopt -s checkwinsize
55 shopt -s mailwarn
56 shopt -s sourcepath
57 shopt -s no_empty_cmd_completion
58 shopt -s histappend histreedit
59 shopt -s extglob # useful for programmable completion
60
61 #-----------------------
62 # Greeting, motd etc...
63 #-----------------------
64
65 # Define some colors first:
66 red='\e[0;31m'
67 RED='\e[1;31m'
68 blue='\e[0;34m'
69 BLUE='\e[1;34m'
70 cyan='\e[0;36m'
71 CYAN='\e[1;36m'
72 NC='\e[0m' # No Color
73 # --> Nice. Has the same effect as using "ansi.sys" in DOS.
74
75 # Looks best on a black background.....
76 echo -e "${CYAN}This is BASH ${RED}${BASH_VERSION%.*}${CYAN} - DISPLAY on ${RED}$DISPLAY${NC}\n"
77 date
78 if [ -x /usr/games/fortune ]; then
79 /usr/games/fortune -s # makes our day a bit more fun.... :-)
80 fi
81
82 function _exit() # function to run upon exit of shell
83 {
84 echo -e "${RED}Hasta la vista, baby${NC}"
85 }
86 trap _exit 0
87
88 #---------------
89 # Shell prompt
90 #---------------
91
92 function fastprompt()
93 {
94 unset PROMPT_COMMAND
95 case $TERM in
96 *term | rxvt )
97 PS1="[\h] \W > \[\033]0;[\u@\h] \w\007\]" ;;
98 *)
99 PS1="[\h] \W > " ;;
100 esac
101 }
102
103 function powerprompt()
104 {
105 _powerprompt()
106 {
107 LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")
108 TIME=$(date +%H:%M)
109 }
110
111 PROMPT_COMMAND=_powerprompt
112 case $TERM in
113 *term | rxvt )
114 PS1="${cyan}[\$TIME \$LOAD]$NC\n[\h \#] \W > \[\033]0;[\u@\h] \w\007\]" ;;
115 linux )
116 PS1="${cyan}[\$TIME - \$LOAD]$NC\n[\h \#] \w > " ;;
117 * )
118 PS1="[\$TIME - \$LOAD]\n[\h \#] \w > " ;;
119 esac
120 }
121
122 powerprompt # this is the default prompt - might be slow
123 # If too slow, use fastprompt instead....
124
125 #===============================================================
126 #
127 # ALIASES AND FUNCTIONS
128 #
129 # Arguably, some functions defined here are quite big
130 # (ie 'lowercase') but my workstation has 512Meg of RAM, so .....
131 # If you want to make this file smaller, these functions can
132 # be converted into scripts.
133 #
134 # Many functions were taken (almost) straight from the bash-2.04
135 # examples.
136 #
137 #===============================================================
138
139 #-------------------
140 # Personnal Aliases
141 #-------------------
142
143 alias rm='rm -i'
144 alias cp='cp -i'
145 alias mv='mv -i'
146 # -> Prevents accidentally clobbering files.
147
148 alias h='history'
149 alias j='jobs -l'
150 alias r='rlogin'
151 alias which='type -all'
152 alias ..='cd ..'
153 alias path='echo -e ${PATH//:/\\n}'
154 alias print='/usr/bin/lp -o nobanner -d $LPDEST' # Assumes LPDEST is defined
155 alias pjet='enscript -h -G -fCourier9 -d $LPDEST' # Pretty-print using enscript
156 alias background='xv -root -quit -max -rmode 5' # put a picture in the background
157 alias vi='vim'
158 alias du='du -h'
159 alias df='df -kh'
160
161 # The 'ls' family (this assumes you use the GNU ls)
162 alias ls='ls -hF --color' # add colors for filetype recognition
163 alias lx='ls -lXB' # sort by extension
164 alias lk='ls -lSr' # sort by size
165 alias la='ls -Al' # show hidden files
166 alias lr='ls -lR' # recursice ls
167 alias lt='ls -ltr' # sort by date
168 alias lm='ls -al |more' # pipe through 'more'
169 alias tree='tree -Cs' # nice alternative to 'ls'
170
171
172 # tailoring 'less'
173 alias more='less'
174 export PAGER=less
175 export LESSCHARSET='latin1'
176 export LESSOPEN='|/usr/bin/lesspipe.sh %s 2>&-' # Use this if lesspipe.sh exists
177 export LESS='-i -N -w -z-4 -g -e -M -X -F -R -P%t?f%f \
178 :stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...'
179
180 # spelling typos - highly personnal :-)
181 alias xs='cd'
182 alias vf='cd'
183 alias moer='more'
184 alias moew='more'
185 alias kk='ll'
186
187 #----------------
188 # a few fun ones
189 #----------------
190
191 function xtitle ()
192 {
193 case $TERM in
194 *term | rxvt)
195 echo -n -e "\033]0;$*\007" ;;
196 *) ;;
197 esac
198 }
199
200 # aliases...
201 alias top='xtitle Processes on $HOST && top'
202 alias make='xtitle Making $(basename $PWD) ; make'
203 alias ncftp="xtitle ncFTP ; ncftp"
204
205 # .. and functions
206 function man ()
207 {
208 xtitle The $(basename $1|tr -d .[:digit:]) manual
209 man -a "$*"
210 }
211
212 function ll(){ ls -l "$@"| egrep "^d" ; ls -lXB "$@" 2>&-| egrep -v "^d|total "; }
213 function xemacs() { { command xemacs -private $* 2>&- & } && disown ;}
214 function te() # wrapper around xemacs/gnuserv
215 {
216 if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then
217 gnuclient -q "$@";
218 else
219 ( xemacs "$@" & );
220 fi
221 }
222
223 #-----------------------------------
224 # File & strings related functions:
225 #-----------------------------------
226
227 function ff() { find . -name '*'$1'*' ; } # find a file
228 function fe() { find . -name '*'$1'*' -exec $2 {} \; ; } # find a file and run $2 on it
229 function fstr() # find a string in a set of files
230 {
231 if [ "$#" -gt 2 ]; then
232 echo "Usage: fstr \"pattern\" [files] "
233 return;
234 fi
235 SMSO=$(tput smso)
236 RMSO=$(tput rmso)
237 find . -type f -name "${2:-*}" -print | xargs grep -sin "$1" | \
238 sed "s/$1/$SMSO$1$RMSO/gI"
239 }
240
241 function cuttail() # cut last n lines in file, 10 by default
242 {
243 nlines=${2:-10}
244 sed -n -e :a -e "1,${nlines}!{P;N;D;};N;ba" $1
245 }
246
247 function lowercase() # move filenames to lowercase
248 {
249 for file ; do
250 filename=${file##*/}
251 case "$filename" in
252 */*) dirname==${file%/*} ;;
253 *) dirname=.;;
254 esac
255 nf=$(echo $filename | tr A-Z a-z)
256 newname="${dirname}/${nf}"
257 if [ "$nf" != "$filename" ]; then
258 mv "$file" "$newname"
259 echo "lowercase: $file --> $newname"
260 else
261 echo "lowercase: $file not changed."
262 fi
263 done
264 }
265
266 function swap() # swap 2 filenames around
267 {
268 local TMPFILE=tmp.$$
269 mv $1 $TMPFILE
270 mv $2 $1
271 mv $TMPFILE $2
272 }
273
274 #-----------------------------------
275 # Process/system related functions:
276 #-----------------------------------
277
278 function my_ps() { ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; }
279 function pp() { my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; }
280
281 # This function is roughly the same as 'killall' on linux
282 # but has no equivalent (that I know of) on Solaris
283 function killps() # kill by process name
284 {
285 local pid pname sig="-TERM" # default signal
286 if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
287 echo "Usage: killps [-SIGNAL] pattern"
288 return;
289 fi
290 if [ $# = 2 ]; then sig=$1 ; fi
291 for pid in $(my_ps| awk '!/awk/ && $0~pat { print $1 }' pat=${!#} ) ; do
292 pname=$(my_ps | awk '$1~var { print $5 }' var=$pid )
293 if ask "Kill process $pid <$pname> with signal $sig?"
294 then kill $sig $pid
295 fi
296 done
297 }
298
299 function my_ip() # get IP adresses
300 {
301 MY_IP=$(/sbin/ifconfig ppp0 | awk '/inet/ { print $2 } ' | sed -e s/addr://)
302 MY_ISP=$(/sbin/ifconfig ppp0 | awk '/P-t-P/ { print $3 } ' | sed -e s/P-t-P://)
303 }
304
305 function ii() # get current host related info
306 {
307 echo -e "\nYou are logged on ${RED}$HOST"
308 echo -e "\nAdditionnal information:$NC " ; uname -a
309 echo -e "\n${RED}Users logged on:$NC " ; w -h
310 echo -e "\n${RED}Current date :$NC " ; date
311 echo -e "\n${RED}Machine stats :$NC " ; uptime
312 echo -e "\n${RED}Memory stats :$NC " ; free
313 my_ip 2>&- ;
314 echo -e "\n${RED}Local IP Address :$NC" ; echo ${MY_IP:-"Not connected"}
315 echo -e "\n${RED}ISP Address :$NC" ; echo ${MY_ISP:-"Not connected"}
316 echo
317 }
318
319
320 # Misc utilities:
321
322 function repeat() # repeat n times command
323 {
324 local i max
325 max=$1; shift;
326 for ((i=1; i <= max ; i++)); do # --> C-like syntax
327 eval "$@";
328 done
329 }
330
331
332 function ask()
333 {
334 echo -n "$@" '[y/n] ' ; read ans
335 case "$ans" in
336 y*|Y*) return 0 ;;
337 *) return 1 ;;
338 esac
339 }
340
341 #=========================================================================
342 #
343 # PROGRAMMABLE COMPLETION - ONLY SINCE BASH-2.04
344 # (Most are taken from the bash 2.05 documentation)
345 # You will in fact need bash-2.05 for some features
346 #
347 #=========================================================================
348
349 if [ "${BASH_VERSION%.*}" \< "2.05" ]; then
350 echo "You will need to upgrade to version 2.05 for programmable completion"
351 return
352 fi
353
354 shopt -s extglob # necessary
355 set +o nounset # otherwise some completions will fail
356
357 complete -A hostname rsh rcp telnet rlogin r ftp ping disk
358 complete -A command nohup exec eval trace gdb
359 complete -A command command type which
360 complete -A export printenv
361 complete -A variable export local readonly unset
362 complete -A enabled builtin
363 complete -A alias alias unalias
364 complete -A function function
365 complete -A user su mail finger
366
367 complete -A helptopic help # currently same as builtins
368 complete -A shopt shopt
369 complete -A stopped -P '%' bg
370 complete -A job -P '%' fg jobs disown
371
372 complete -A directory mkdir rmdir
373 complete -A directory -o default cd
374
375 complete -f -d -X '*.gz' gzip
376 complete -f -d -X '*.bz2' bzip2
377 complete -f -o default -X '!*.gz' gunzip
378 complete -f -o default -X '!*.bz2' bunzip2
379 complete -f -o default -X '!*.pl' perl perl5
380 complete -f -o default -X '!*.ps' gs ghostview ps2pdf ps2ascii
381 complete -f -o default -X '!*.dvi' dvips dvipdf xdvi dviselect dvitype
382 complete -f -o default -X '!*.pdf' acroread pdf2ps
383 complete -f -o default -X '!*.+(pdf|ps)' gv
384 complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf
385 complete -f -o default -X '!*.tex' tex latex slitex
386 complete -f -o default -X '!*.lyx' lyx
387 complete -f -o default -X '!*.+(jpg|gif|xpm|png|bmp)' xv gimp
388 complete -f -o default -X '!*.mp3' mpg123
389 complete -f -o default -X '!*.ogg' ogg123
390
391
392 # This is a 'universal' completion function - it works when commands have
393 # a so-called 'long options' mode , ie: 'ls --all' instead of 'ls -a'
394 _universal_func ()
395 {
396 case "$2" in
397 -*) ;;
398 *) return ;;
399 esac
400
401 case "$1" in
402 \~*) eval cmd=$1 ;;
403 *) cmd="$1" ;;
404 esac
405 COMPREPLY=( $("$cmd" --help | sed -e '/--/!d' -e 's/.*--\([^ ]*\).*/--\1/'| \
406 grep ^"$2" |sort -u) )
407 }
408 complete -o default -F _universal_func ldd wget bash id info
409
410
411 _make_targets ()
412 {
413 local mdef makef gcmd cur prev i
414
415 COMPREPLY=()
416 cur=${COMP_WORDS[COMP_CWORD]}
417 prev=${COMP_WORDS[COMP_CWORD-1]}
418
419 # if prev argument is -f, return possible filename completions.
420 # we could be a little smarter here and return matches against
421 # `makefile Makefile *.mk', whatever exists
422 case "$prev" in
423 -*f) COMPREPLY=( $(compgen -f $cur ) ); return 0;;
424 esac
425
426 # if we want an option, return the possible posix options
427 case "$cur" in
428 -) COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;;
429 esac
430
431 # make reads `makefile' before `Makefile'
432 if [ -f makefile ]; then
433 mdef=makefile
434 elif [ -f Makefile ]; then
435 mdef=Makefile
436 else
437 mdef=*.mk # local convention
438 fi
439
440 # before we scan for targets, see if a makefile name was specified
441 # with -f
442 for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do
443 if [[ ${COMP_WORDS[i]} == -*f ]]; then
444 eval makef=${COMP_WORDS[i+1]} # eval for tilde expansion
445 break
446 fi
447 done
448
449 [ -z "$makef" ] && makef=$mdef
450
451 # if we have a partial word to complete, restrict completions to
452 # matches of that word
453 if [ -n "$2" ]; then gcmd='grep "^$2"' ; else gcmd=cat ; fi
454
455 # if we don't want to use *.mk, we can take out the cat and use
456 # test -f $makef and input redirection
457 COMPREPLY=( $(cat $makef 2>/dev/null | awk 'BEGIN {FS=":"} /^[^.# ][^=]*:/ {print $1}' | tr -s ' ' '\012' | sort -u | eval $gcmd ) )
458 }
459
460 complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake
461
462 _configure_func ()
463 {
464 case "$2" in
465 -*) ;;
466 *) return ;;
467 esac
468
469 case "$1" in
470 \~*) eval cmd=$1 ;;
471 *) cmd="$1" ;;
472 esac
473
474 COMPREPLY=( $("$cmd" --help | awk '{if ($1 ~ /--.*/) print $1}' | grep ^"$2" | sort -u) )
475 }
476
477 complete -F _configure_func configure
478
479 # cvs(1) completion
480 _cvs ()
481 {
482 local cur prev
483 COMPREPLY=()
484 cur=${COMP_WORDS[COMP_CWORD]}
485 prev=${COMP_WORDS[COMP_CWORD-1]}
486
487 if [ $COMP_CWORD -eq 1 ] || [ "${prev:0:1}" = "-" ]; then
488 COMPREPLY=( $( compgen -W 'add admin checkout commit diff \
489 export history import log rdiff release remove rtag status \
490 tag update' $cur ))
491 else
492 COMPREPLY=( $( compgen -f $cur ))
493 fi
494 return 0
495 }
496 complete -F _cvs cvs
497
498
499 _killall ()
500 {
501 local cur prev
502 COMPREPLY=()
503 cur=${COMP_WORDS[COMP_CWORD]}
504
505 # get a list of processes (the first sed evaluation
506 # takes care of swapped out processes, the second
507 # takes care of getting the basename of the process)
508 COMPREPLY=( $( /usr/bin/ps -u $USER -o comm | \
509 sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \
510 awk '{if ($0 ~ /^'$cur'/) print $0}' ))
511
512 return 0
513 }
514
515 complete -F _killall killall killps
516
517 # Local Variables:
518 # mode:shell-script
519 # sh-shell:bash
520 # End: |