(M)  s i s t e m a   o p e r a c i o n a l   m a g n u x   l i n u x ~/ · documentação · suporte · sobre

 

Appendix C. A Sample .bashrc File

The ~/.bashrc file determines the behavior of the shell, and of shell scripts. A proper understanding of this file can lead to more effective use of scripts.

Emmanuel Rouat contributed the following very elaborate .bashrc file. He wrote it for a Solaris system, but it (mostly) works for other flavors of UNIX as well. Study this file carefully, and feel free to reuse code snippets and functions from it in your own .bashrc file and even in your scripts.

Example C-1. Sample .bashrc file

#===============================================================
#
# PERSONAL $HOME/.bashrc FILE for bash-2.04 (or later) 
#              by Emmanuel Rouat
#
# This file is read (normally) by interactive shells only.
# Here is the place to define your aliases, functions and
# other interactive features like your prompt.
# 
# This file was designed for Solaris 
#
#===============================================================



#-----------------------------------
# Source global definitions (if any)
#-----------------------------------

if [ -f /etc/bashrc ]; then
	. /etc/bashrc  # Read system bash init file, if exists.
fi


#-------------------------------------------------------------
# Automatic setting of $DISPLAY (if not set already)
# This works for linux and solaris - your mileage may vary....
#-------------------------------------------------------------


if [ -z ${DISPLAY:=""} ]; then
    DISPLAY=$(who am i)
    DISPLAY=${DISPLAY%%\!*}
    if [ -n "$DISPLAY" ]; then
	export DISPLAY=$DISPLAY:0.0
    else
	export DISPLAY=":0.0"  # fallback    
    fi
fi


#---------------
# Some settings
#---------------

set -o notify
set -o noclobber
set -o ignoreeof
set -o nounset
#set -o xtrace		# useful for debuging 

shopt -s cdspell 
shopt -s cdable_vars
shopt -s checkhash 
shopt -s checkwinsize 
shopt -s mailwarn
shopt -s sourcepath
shopt -s no_empty_cmd_completion
shopt -s histappend histreedit
shopt -s extglob	# useful for programmable completion



#-----------------------
# Greeting, motd etc...
#-----------------------

# Define some colors first:
red='\e[0;31m'
RED='\e[1;31m'
blue='\e[0;34m'
BLUE='\e[1;34m'
cyan='\e[0;36m'
CYAN='\e[1;36m'
NC='\e[0m'		# No Color

# Looks best on a black background.....
echo -e "${CYAN}This is BASH ${RED}${BASH_VERSION%.*}${CYAN} - DISPLAY on ${RED}$DISPLAY${NC}\n"
date


function _exit()	# function to run upon exit of shell
{
    echo -e "${RED}Hasta la vista, baby${NC}"
}
trap _exit 0

#---------------
# Shell prompt
#---------------


function fastprompt()
{
    unset PROMPT_COMMAND
    case $TERM in
	xterm | rxvt | dtterm )	
	    PS1="[\h] \W > \[\033]0;[\u@\h] \w\007\]" ;;
	*) 
	    PS1="[\h] \W > " ;;
    esac
}


function powerprompt()
{
    _powerprompt() 
    { 
	LOAD=$(uptime|sed -e "s/.*: \([^,]*\).*/\1/" -e "s/ //g")	
	TIME=$(date +%H:%M)
    } 
  
    PROMPT_COMMAND=_powerprompt
    case $TERM in
	xterm | dtterm | rxvt  )
	    PS1="${cyan}[\$TIME \$LOAD]$NC\n[\h \#] \W > \[\033]0;[\u@\h] \w\007\]" ;;
	linux )
	    PS1="${cyan}[\$TIME - \$LOAD]$NC\n[\h \#] \w > " ;;
	* )
	    PS1="[\$TIME - \$LOAD]\n[\h \#] \w > " ;;
    esac
}

powerprompt	# this is the default prompt - might be slow
		# If too slow, use fastprompt instead....



#===============================================================
#
# ALIASES AND FUNCTIONS 
#
# Arguably, some functions defined here are quite big 
# (ie 'lowercase') but my workstation has 512Meg of RAM, so .....
# If you want to make this file smaller, these functions can
# be converted into scripts.
#
#===============================================================

#-------------------
# Personnal Aliases
#-------------------

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias h='history'
alias j='jobs -l'
alias r='rlogin'
alias which='type -a'
alias ..='cd ..'
alias path='echo -e ${PATH//:/\\n}'
alias print='/usr/bin/lp -o nobanner -d $LPDEST'

alias la='ls -Al'
alias lr='ls -lR'
alias lt='ls -ltr'  
alias lm='ls -al |more'

# spelling typos

alias xs='cd'
alias vf='cd'
alias moer='more'
alias moew='more'
alias kk='ll'


#-----------------------------------------
# Environment dependent aliases/variables
#-----------------------------------------


if [ -d $FREE/bin ] ; then	# use gnu/free stuff
# Condition test unnecessary on a Linux or BSD system.

    alias vi='vim'
    alias csh='tcsh'
    alias du='du -h'
    alias df='df -kh'
    alias ls='ls -hF --color'
    alias lx='ls -lXB'
    alias lk='ls -lSr'
    alias pjet='enscript -h -G -fCourier9 -d $LPDEST '
    alias background='xv -root -quit -max -rmode 5'

    alias more='less'
    export PAGER=less
    export LESSCHARSET='latin1'
    export LESSOPEN='|lesspipe.sh %s'
    export LESS='-i  -e -M -X -F -R -P%t?f%f \
:stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...'

else				# use regular solaris stuff

    alias df='df -k'
    alias ls='ls -F'

fi


#----------------
# a few fun ones
#----------------

function xtitle () 
{ 
    case $TERM in
	xterm* | dtterm | rxvt) 
	    echo -n -e "\033]0;$*\007" ;;
	*)  ;;
    esac
}

alias top='xtitle Processes on $HOST && top'
alias make='xtitle Making $(basename $PWD) ; make'
alias ncftp="xtitle ncFTP ; ncftp"


#---------------
# and functions
#---------------

function man ()
{
    xtitle The $(basename $1|tr -d .[:digit:]) manual
    /usr/bin/man -a "$*"
}

#-----------------------------------------
# Environment dependent functions
#-----------------------------------------

# Note: we mustn't mix these with alias definitions in the same 'if/fi'
# construct because alias expansion wouldn't occur in some functions here, 
# like 'll' that uses ls (which is an alias).


if [ -d $FREE/bin ] ; then	# use gnu/free stuff

    function ll(){ ls -l  $*| egrep "^d" ; ls -lh  $* 2>&-| egrep -v "^d|total "; }
    function xemacs() { { command xemacs -private $* 2>&- & } && disown ;}
    function te()  # wrapper around xemacs/gnuserv
    {
	if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then
	    gnuclient -q $@;
	else
	    ( xemacs $@ & );
	fi
    }

else				# use solaris stuff

    function ll(){ ls -l $* |egrep "^d"; ls -l $* 2>&- |egrep -v "^d|total" ;}
    function lk() { \ls -lF  $* | egrep -v "^d|^total" | sort -n -k 5,5 ;}    
    function te() { ( dtpad "$@" &)  ;}

fi


#-----------------------------------
# File & strings related functions:
#-----------------------------------

function ff() { find . -name '*'$1'*' ; }
function fe() { find . -name '*'$1'*' -exec $2 {} \; ; }
function fstr() # find a string in a set of files
{
    if [ "$#" -gt 2 ]; then
        echo "Usage: fstr \"pattern\" [files] "
    return;
    fi
    find . -type f -name "${2:-*}" -print | xargs grep -n "$1"
}
function cuttail() # cut last n lines in file
{
    nlines=$1
    sed -n -e :a -e "1,${nlines}!{P;N;D;};N;ba" $2 
}

function lowercase()  # move filenames to lowercase
{
    for file ; do
        filename=${file##*/}
        case "$filename" in
        */*) dirname==${file%/*} ;;
        *) dirname=.;;
        esac
        nf=$(echo $filename | tr A-Z a-z)
        newname="${dirname}/${nf}"
        if [ "$nf" != "$filename" ]; then
            mv "$file" "$newname"
            echo "lowercase: $file --> $newname"
        else
            echo "lowercase: $file not changed."
        fi
    done
}

function swap()		# swap 2 filenames around
{
    local TMPFILE=tmp.$$
    mv $1 $TMPFILE
    mv $2 $1
    mv $TMPFILE $2
}


# Process/system related functions:

alias my_ps='/usr/bin/ps -u "$USER" -o user,pid,ppid,pcpu,pmem,args'
function pp() { my_ps | nawk '!/nawk/ && $0~pat' pat=${1:-".*"} ; }
function killps()	# Kill process by name
{			# works with gawk too
    local pid pname sig="-TERM" # default signal
    if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then 
	echo "Usage: killps [-SIGNAL] pattern"
	return;
    fi
    if [ $# = 2 ]; then sig=$1 ; fi
    for pid in $(my_ps | nawk '!/nawk/ && $0~pat { print $2 }' pat=${!#}) ; do
	pname=$(my_ps | nawk '$2~var { print $6 }' var=$pid )
	if ask "Kill process $pid <$pname> with signal $sig ? "
	    then kill $sig $pid
	fi
    done
}

function ii()   # get current host related info
{
    echo -e "\nYou are logged on ${RED}$HOST"
    echo -e "\nAdditionnal information:$NC " ; uname -a
    echo -e "\n${RED}IP Address :$NC" ; ypmatch $HOSTNAME hosts
    echo -e "\n${RED}Users logged on:$NC " ; /usr/ucb/users
    echo -e "\n${RED}Current date :$NC " ; date
    echo -e "\n${RED}Machine stats :$NC " ; uptime
    echo -e "\n${RED}Memory stats :$NC " ; vmstat
    echo -e "\n${RED}NIS Server :$NC " ; ypwhich
    echo
}
function corename()   # get name of app that created core
{
    local file name;
    file=${1:-"core"}
    set -- $(adb $file < /dev/null 2>&1 | sed 1q)
    name=${7#??}
    echo $file: ${name%??}
}
# Misc utilities:

function repeat()	# repeat n times command
{
    local i max
    max=$1; shift;
    for ((i=1; i <= max ; i++)); do
	eval "$@";
    done
}
	

function ask()
{
    echo -n "$@" '[y/n] ' ; read ans
    case "$ans" in
        y*|Y*) return 0 ;;
        *) return 1 ;;
    esac
}



#=========================================================================
#
# PROGRAMMABLE COMPLETION - ONLY IN BASH-2.04
#
#=========================================================================

if [ "${BASH_VERSION%.*}" \< "2.04" ]; then
    echo "No programmable completion available"
    return
fi
   
shopt -s extglob	# necessary

complete -A hostname   rsh rcp telnet rlogin r ftp ping disk
complete -A command    nohup exec eval trace truss strace sotruss gdb
complete -A command    command type which 
complete -A export     printenv
complete -A variable   export local readonly unset
complete -A enabled    builtin
complete -A alias      alias unalias
complete -A function   function
complete -A user       su mail finger

complete -A helptopic  help	# currently same as builtins
complete -A shopt      shopt
complete -A stopped -P '%' bg
complete -A job -P '%'     fg jobs disown

complete -A directory  mkdir rmdir

complete -f -X '*.gz'   gzip
complete -f -X '!*.ps'  gs ghostview gv
complete -f -X '!*.pdf' acroread
complete -f -X '!*.+(gif|jpg|jpeg|GIF|JPG|bmp)' xv gimp

 
_make_targets ()
{
    local mdef makef gcmd cur prev i

    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}
    prev=${COMP_WORDS[COMP_CWORD-1]}

    # if prev argument is -f, return possible filename completions.
    # we could be a little smarter here and return matches against
    # `makefile Makefile *.mk', whatever exists
    case "$prev" in
	-*f)	COMPREPLY=( $(compgen -f $cur ) ); return 0;;
    esac

    # if we want an option, return the possible posix options
    case "$cur" in
	-)	COMPREPLY=(-e -f -i -k -n -p -q -r -S -s -t); return 0;;
    esac

    # make reads `makefile' before `Makefile'
    if [ -f makefile ]; then
	mdef=makefile
    elif [ -f Makefile ]; then
	mdef=Makefile
    else
	mdef=*.mk		# local convention
    fi

    # before we scan for targets, see if a makefile name was specified
    # with -f
    for (( i=0; i < ${#COMP_WORDS[@]}; i++ )); do
	if [[ ${COMP_WORDS[i]} == -*f ]]; then
	    eval makef=${COMP_WORDS[i+1]}	# eval for tilde expansion
	    break
	fi
    done

	[ -z "$makef" ] && makef=$mdef

    # if we have a partial word to complete, restrict completions to
    # matches of that word
    if [ -n "$2" ]; then gcmd='grep "^$2"' ; else gcmd=cat ; fi

    # if we don't want to use *.mk, we can take out the cat and use
    # test -f $makef and input redirection	
    COMPREPLY=( $(cat $makef 2>/dev/null | awk 'BEGIN {FS=":"} /^[^.# 	][^=]*:/ {print $1}' | tr -s ' ' '\012' | sort -u | eval $gcmd ) )
}

complete -F _make_targets -X '+($*|*.[cho])' make gmake pmake


_configure_func ()
{
    case "$2" in
	-*)	;;
	*)	return ;;
    esac

    case "$1" in
	\~*)	eval cmd=$1 ;;
	*)	cmd="$1" ;;
    esac

    COMPREPLY=( $("$cmd" --help | awk '{if ($1 ~ /--.*/) print $1}' | grep ^"$2" | sort -u) )
}

complete -F _configure_func configure

_killps ()
{
    local cur prev
    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}

    # get a list of processes (the first sed evaluation
    # takes care of swapped out processes, the second
    # takes care of getting the basename of the process)
    COMPREPLY=( $( /usr/bin/ps -u $USER -o comm  | \
	sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \
	awk '{if ($0 ~ /^'$cur'/) print $0}' ))

    return 0
}
complete -F _killps killps



# Local Variables:
# mode:shell-script
# sh-shell:bash
# End: