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] \w007円\]" ;;
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] \w007円\]" ;;
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: |