# =============================================================== # # # PERSONAL $HOME/.bashrc FILE for bash-3.0 (or later) # By Emmanuel Rouat [no-email] # # Last modified: Tue Nov 20 22:04:47 CET 2012 # This file is normally read by interactive shells only. #+ Here is the place to define your aliases, functions and #+ other interactive features like your prompt. # # The majority of the code here assumes you are on a GNU #+ system (most likely a Linux box) and is often based on code #+ found on Usenet or Internet. # # See for instance: # http://tldp.org/LDP/abs/html/index.html # http://www.caliban.org/bash # http://www.shelldorado.com/scripts/categories.html # http://www.dotfiles.org # # The choice of colors was done for a shell with a dark background #+ (white on black), and this is usually also suited for pure text-mode #+ consoles (no X server available). If you use a white background, #+ you'll have to do some other choices for readability. # # This bashrc file is a bit overcrowded. # Remember, it is just just an example. # Tailor it to your needs. # # =============================================================== # # --> Comments added by HOWTO author. # If not running interactively, don't do anything [ -z "$PS1" ] && return #------------------------------------------------------------- # Source global definitions (if any) #------------------------------------------------------------- if [ -f /etc/bashrc ]; then . /etc/bashrc # --> Read /etc/bashrc, if present. fi #-------------------------------------------------------------- # Automatic setting of $DISPLAY (if not set already). # This works for me - your mileage may vary. . . . # The problem is that different types of terminals give #+ different answers to 'who am i' (rxvt in particular can be #+ troublesome) - however this code seems to work in a majority #+ of cases. #-------------------------------------------------------------- function get_xserver () { case $TERM in xterm ) XSERVER=$(who am i | awk '{print $NF}' | tr -d ')''(' ) # Ane-Pieter Wieringa suggests the following alternative: # I_AM=$(who am i) # SERVER=${I_AM#*(} # SERVER=${SERVER%*)} XSERVER=${XSERVER%%:*} ;; aterm | rxvt) # Find some code that works here. ... ;; esac } if [ -z ${DISPLAY:=""} ]; then get_xserver if [[ -z ${XSERVER} || ${XSERVER} == $(hostname) || ${XSERVER} == "unix" ]]; then DISPLAY=":0.0" # Display on local host. else DISPLAY=${XSERVER}:0.0 # Display on remote host. fi fi export DISPLAY #------------------------------------------------------------- # Some settings #------------------------------------------------------------- #set -o nounset # These two options are useful for debugging. #set -o xtrace alias debug="set -o nounset; set -o xtrace" ulimit -S -c 0 # Don't want coredumps. set -o notify set -o noclobber set -o ignoreeof # Enable options: shopt -s cdspell shopt -s cdable_vars shopt -s checkhash shopt -s checkwinsize shopt -s sourcepath shopt -s no_empty_cmd_completion shopt -s cmdhist shopt -s histappend histreedit histverify shopt -s extglob # Necessary for programmable completion. # Disable options: shopt -u mailwarn unset MAILCHECK # Don't want my shell to warn me of incoming mail. #------------------------------------------------------------- # Greeting, motd etc. ... #------------------------------------------------------------- # Color definitions (taken from Color Bash Prompt HowTo). # Some colors might look different of some terminals. # For example, I see 'Bold Red' as 'orange' on my screen, # hence the 'Green' 'BRed' 'Red' sequence I often use in my prompt. # Normal Colors Black='\e[0;30m' # Black Red='\e[0;31m' # Red Green='\e[0;32m' # Green Yellow='\e[0;33m' # Yellow Blue='\e[0;34m' # Blue Purple='\e[0;35m' # Purple Cyan='\e[0;36m' # Cyan White='\e[0;37m' # White # Bold BBlack='\e[1;30m' # Black BRed='\e[1;31m' # Red BGreen='\e[1;32m' # Green BYellow='\e[1;33m' # Yellow BBlue='\e[1;34m' # Blue BPurple='\e[1;35m' # Purple BCyan='\e[1;36m' # Cyan BWhite='\e[1;37m' # White # Background On_Black='\e[40m' # Black On_Red='\e[41m' # Red On_Green='\e[42m' # Green On_Yellow='\e[43m' # Yellow On_Blue='\e[44m' # Blue On_Purple='\e[45m' # Purple On_Cyan='\e[46m' # Cyan On_White='\e[47m' # White NC="\e[m" # Color Reset ALERT=${BWhite}${On_Red} # Bold White on red background echo -e "${BCyan}This is BASH ${BRed}${BASH_VERSION%.*}${BCyan}\ - DISPLAY on ${BRed}$DISPLAY${NC}\n" date if [ -x /usr/games/fortune ]; then /usr/games/fortune -s # Makes our day a bit more fun.... :-) fi function _exit() # Function to run upon exit of shell. { echo -e "${BRed}Hasta la vista, baby${NC}" } trap _exit EXIT #------------------------------------------------------------- # Shell Prompt - for many examples, see: # http://www.debian-administration.org/articles/205 # http://www.askapache.com/linux/bash-power-prompt.html # http://tldp.org/HOWTO/Bash-Prompt-HOWTO # https://github.com/nojhan/liquidprompt #------------------------------------------------------------- # Current Format: [TIME USER@HOST PWD] > # TIME: # Green == machine load is low # Orange == machine load is medium # Red == machine load is high # ALERT == machine load is very high # USER: # Cyan == normal user # Orange == SU to user # Red == root # HOST: # Cyan == local session # Green == secured remote connection (via ssh) # Red == unsecured remote connection # PWD: # Green == more than 10% free disk space # Orange == less than 10% free disk space # ALERT == less than 5% free disk space # Red == current user does not have write privileges # Cyan == current filesystem is size zero (like /proc) # >: # White == no background or suspended jobs in this shell # Cyan == at least one background job in this shell # Orange == at least one suspended job in this shell # # Command is added to the history file each time you hit enter, # so it's available to all shells (using 'history -a'). # Test connection type: if [ -n "${SSH_CONNECTION}" ]; then CNX=${Green} # Connected on remote machine, via ssh (good). elif [[ "${DISPLAY%%:0*}" != "" ]]; then CNX=${ALERT} # Connected on remote machine, not via ssh (bad). else CNX=${BCyan} # Connected on local machine. fi # Test user type: if [[ ${USER} == "root" ]]; then SU=${Red} # User is root. elif [[ ${USER} != $(logname) ]]; then SU=${BRed} # User is not login user. else SU=${BCyan} # User is normal (well ... most of us are). fi NCPU=$(grep -c 'processor' /proc/cpuinfo) # Number of CPUs SLOAD=$(( 100*${NCPU} )) # Small load MLOAD=$(( 200*${NCPU} )) # Medium load XLOAD=$(( 400*${NCPU} )) # Xlarge load # Returns system load as percentage, i.e., '40' rather than '0.40)'. function load() { local SYSLOAD=$(cut -d " " -f1 /proc/loadavg | tr -d '.') # System load of the current host. echo $((10#$SYSLOAD)) # Convert to decimal. } # Returns a color indicating system load. function load_color() { local SYSLOAD=$(load) if [ ${SYSLOAD} -gt ${XLOAD} ]; then echo -en ${ALERT} elif [ ${SYSLOAD} -gt ${MLOAD} ]; then echo -en ${Red} elif [ ${SYSLOAD} -gt ${SLOAD} ]; then echo -en ${BRed} else echo -en ${Green} fi } # Returns a color according to free disk space in $PWD. function disk_color() { if [ ! -w "${PWD}" ] ; then echo -en ${Red} # No 'write' privilege in the current directory. elif [ -s "${PWD}" ] ; then local used=$(command df -P "$PWD" | awk 'END {print $5} {sub(/%/,"")}') if [ ${used} -gt 95 ]; then echo -en ${ALERT} # Disk almost full (>95%). elif [ ${used} -gt 90 ]; then echo -en ${BRed} # Free disk space almost gone. else echo -en ${Green} # Free disk space is ok. fi else echo -en ${Cyan} # Current directory is size '0' (like /proc, /sys etc). fi } # Returns a color according to running/suspended jobs. function job_color() { if [ $(jobs -s | wc -l) -gt "0" ]; then echo -en ${BRed} elif [ $(jobs -r | wc -l) -gt "0" ] ; then echo -en ${BCyan} fi } # Adds some text in the terminal frame (if applicable). # Now we construct the prompt. PROMPT_COMMAND="history -a" case ${TERM} in *term | rxvt | linux) PS1="\[\$(load_color)\][\A\[${NC}\] " # Time of day (with load info): PS1="\[\$(load_color)\][\A\[${NC}\] " # User@Host (with connection type info): PS1=${PS1}"\[${SU}\]\u\[${NC}\]@\[${CNX}\]\h\[${NC}\] " # PWD (with 'disk space' info): PS1=${PS1}"\[\$(disk_color)\]\W]\[${NC}\] " # Prompt (with 'job' info): PS1=${PS1}"\[\$(job_color)\]>\[${NC}\] " # Set title of current xterm: PS1=${PS1}"\[\e]0;[\u@\h] \w\a\]" ;; *) PS1="(\A \u@\h \W) > " # --> PS1="(\A \u@\h \w) > " # --> Shows full pathname of current dir. ;; esac export TIMEFORMAT=$'\nreal %3R\tuser %3U\tsys %3S\tpcpu %P\n' export HISTIGNORE="&:bg:fg:ll:h" export HISTTIMEFORMAT="$(echo -e ${BCyan})[%d/%m %H:%M:%S]$(echo -e ${NC}) " export HISTCONTROL=ignoredups export HOSTFILE=$HOME/.hosts # Put a list of remote hosts in ~/.hosts #============================================================ # # ALIASES AND FUNCTIONS # # Arguably, some functions defined here are quite big. # If you want to make this file smaller, these functions can #+ be converted into scripts and removed from here. # #============================================================ #------------------- # Personnal Aliases #------------------- alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # -> Prevents accidentally clobbering files. alias mkdir='mkdir -p' alias h='history' alias j='jobs -l' alias which='type -a' alias ..='cd ..' # Pretty-print of some PATH variables: alias path='echo -e ${PATH//:/\\n}' alias libpath='echo -e ${LD_LIBRARY_PATH//:/\\n}' alias du='du -kh' # Makes a more readable output. alias df='df -kTh' #------------------------------------------------------------- # The 'ls' family (this assumes you use a recent GNU ls). #------------------------------------------------------------- # Add colors for filetype and human-readable sizes by default on 'ls': alias ls='ls -h --color' alias lx='ls -lXB' # Sort by extension. alias lk='ls -lSr' # Sort by size, biggest last. alias lt='ls -ltr' # Sort by date, most recent last. alias lc='ls -ltcr' # Sort by/show change time,most recent last. alias lu='ls -ltur' # Sort by/show access time,most recent last. # The ubiquitous 'll': directories first, with alphanumeric sorting: alias ll="ls -lv --group-directories-first" alias lm='ll |more' # Pipe through 'more' alias lr='ll -R' # Recursive ls. alias la='ll -A' # Show hidden files. alias tree='tree -Csuh' # Nice alternative to 'recursive ls' ... alias update="sudo apt-get update && sudo apt-get upgrade" #------------------------------------------------------------- # Tailoring 'less' #------------------------------------------------------------- alias more='less' export PAGER=less export LESSCHARSET='latin1' export LESSOPEN='|/usr/bin/lesspipe.sh %s 2>&-' # Use this if lesspipe.sh exists. export LESS='-i -N -w -z-4 -g -e -M -X -F -R -P%t?f%f \ :stdin .?pb%pb\%:?lbLine %lb:?bbByte %bb:-...' # LESS man page colors (makes Man pages more readable). export LESS_TERMCAP_mb=$'\E[01;31m' export LESS_TERMCAP_md=$'\E[01;31m' export LESS_TERMCAP_me=$'\E[0m' export LESS_TERMCAP_se=$'\E[0m' export LESS_TERMCAP_so=$'\E[01;44;33m' export LESS_TERMCAP_ue=$'\E[0m' export LESS_TERMCAP_us=$'\E[01;32m' #------------------------------------------------------------- # Spelling typos - highly personnal and keyboard-dependent :-) #------------------------------------------------------------- alias xs='cd' alias vf='cd' alias moer='more' alias moew='more' alias kk='ll' #------------------------------------------------------------- # A few fun ones #------------------------------------------------------------- # Adds some text in the terminal frame (if applicable). function xtitle() { case "$TERM" in *term* | rxvt) echo -en "\e]0;$*\a" ;; *) ;; esac } # Aliases that use xtitle alias top='xtitle Processes on $HOST && top' alias make='xtitle Making $(basename $PWD) ; make' # .. and functions function man() { for i ; do xtitle The $(basename $1|tr -d .[:digit:]) manual command man -a "$i" done } #------------------------------------------------------------- # Make the following commands run in background automatically: #------------------------------------------------------------- function te() # wrapper around xemacs/gnuserv { if [ "$(gnuclient -batch -eval t 2>&-)" == "t" ]; then gnuclient -q "$@"; else ( xemacs "$@" &); fi } function soffice() { command soffice "$@" & } function firefox() { command firefox "$@" & } function xpdf() { command xpdf "$@" & } #------------------------------------------------------------- # File & strings related functions: #------------------------------------------------------------- # Find a file with a pattern in name: function ff() { find . -type f -iname '*'"$*"'*' -ls ; } # Find a file with pattern $1 in name and Execute $2 on it: function fe() { find . -type f -iname '*'"${1:-}"'*' \ -exec ${2:-file} {} \; ; } # Find a pattern in a set of files and highlight them: #+ (needs a recent version of egrep). function fstr() { OPTIND=1 local mycase="" local usage="fstr: find string in files. Usage: fstr [-i] \"pattern\" [\"filename pattern\"] " while getopts :it opt do case "$opt" in i) mycase="-i " ;; *) echo "$usage"; return ;; esac done shift $(( $OPTIND - 1 )) if [ "$#" -lt 1 ]; then echo "$usage" return; fi find . -type f -name "${2:-*}" -print0 | \ xargs -0 egrep --color=always -sn ${case} "$1" 2>&- | more } function swap() { # Swap 2 filenames around, if they exist (from Uzi's bashrc). local TMPFILE=tmp.$$ [ $# -ne 2 ] && echo "swap: 2 arguments needed" && return 1 [ ! -e $1 ] && echo "swap: $1 does not exist" && return 1 [ ! -e $2 ] && echo "swap: $2 does not exist" && return 1 mv "$1" $TMPFILE mv "$2" "$1" mv $TMPFILE "$2" } function extract() # Handy Extract Program { if [ -f $1 ] ; then case $1 in *.tar.bz2) tar xvjf $1 ;; *.tar.gz) tar xvzf $1 ;; *.bz2) bunzip2 $1 ;; *.rar) unrar x $1 ;; *.gz) gunzip $1 ;; *.tar) tar xvf $1 ;; *.tbz2) tar xvjf $1 ;; *.tgz) tar xvzf $1 ;; *.zip) unzip $1 ;; *.Z) uncompress $1 ;; *.7z) 7z x $1 ;; *) echo "'$1' cannot be extracted via >extract<" ;; esac else echo "'$1' is not a valid file!" fi } # Creates an archive (*.tar.gz) from given directory. function maketar() { tar cvzf "${1%%/}.tar.gz" "${1%%/}/"; } # Create a ZIP archive of a file or folder. function makezip() { zip -r "${1%%/}.zip" "$1" ; } # Make your directories and files access rights sane. function sanitize() { chmod -R u=rwX,g=rX,o= "$@" ;} #------------------------------------------------------------- # Process/system related functions: #------------------------------------------------------------- function my_ps() { ps $@ -u $USER -o pid,%cpu,%mem,bsdtime,command ; } function pp() { my_ps f | awk '!/awk/ && $0~var' var=${1:-".*"} ; } function killps() # kill by process name { 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| awk '!/awk/ && $0~pat { print $1 }' pat=${!#} ) do pname=$(my_ps | awk '$1~var { print $5 }' var=$pid ) if ask "Kill process $pid <$pname> with signal $sig?" then kill $sig $pid fi done } function mydf() # Pretty-print of 'df' output. { # Inspired by 'dfc' utility. for fs ; do if [ ! -d $fs ] then echo -e $fs" :No such file or directory" ; continue fi local info=( $(command df -P $fs | awk 'END{ print $2,$3,$5 }') ) local free=( $(command df -Pkh $fs | awk 'END{ print $4 }') ) local nbstars=$(( 20 * ${info[1]} / ${info[0]} )) local out="[" for ((j=0;j<20;j++)); do if [ ${j} -lt ${nbstars} ]; then out=$out"*" else out=$out"-" fi done out=${info[2]}" "$out"] ("$free" free on "$fs")" echo -e $out done } function my_ip() # Get IP adress on ethernet. { MY_IP=$(/sbin/ifconfig eth0 | awk '/inet/ { print $2 } ' | sed -e s/addr://) echo ${MY_IP:-"Not connected"} } function ii() # Get current host related info. { echo -e "\nYou are logged on ${BRed}$HOST" echo -e "\n${BRed}Additionnal information:$NC " ; uname -a echo -e "\n${BRed}Users logged on:$NC " ; w -hs | cut -d " " -f1 | sort | uniq echo -e "\n${BRed}Current date :$NC " ; date echo -e "\n${BRed}Machine stats :$NC " ; uptime echo -e "\n${BRed}Memory stats :$NC " ; free echo -e "\n${BRed}Diskspace :$NC " ; mydf / $HOME echo -e "\n${BRed}Local IP Address :$NC" ; my_ip echo -e "\n${BRed}Open connections :$NC "; netstat -pan --inet; echo } #------------------------------------------------------------- # Misc utilities: #------------------------------------------------------------- function repeat() # Repeat n times command. { local i max max=$1; shift; for ((i=1; i <= max ; i++)); do # --> C-like syntax eval "$@"; done } function ask() # See 'killps' for example of use. { echo -n "$@" '[y/n] ' ; read ans case "$ans" in y*|Y*) return 0 ;; *) return 1 ;; esac } function corename() # Get name of app that created a corefile. { for file ; do echo -n $file : ; gdb --core=$file --batch | head -1 done } #========================================================================= # # PROGRAMMABLE COMPLETION SECTION # Most are taken from the bash 2.05 documentation and from Ian McDonald's # 'Bash completion' package (http://www.caliban.org/bash/#completion) # You will in fact need bash more recent then 3.0 for some features. # # Note that most linux distributions now provide many completions # 'out of the box' - however, you might need to make your own one day, # so I kept those here as examples. #========================================================================= if [ "${BASH_VERSION%.*}" \< "3.0" ]; then echo "You will need to upgrade to version 3.0 for full \ programmable completion features" return fi shopt -s extglob # Necessary. complete -A hostname rsh rcp telnet rlogin ftp ping disk 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 -A directory -o default cd # Compression complete -f -o default -X '*.+(zip|ZIP)' zip complete -f -o default -X '!*.+(zip|ZIP)' unzip complete -f -o default -X '*.+(z|Z)' compress complete -f -o default -X '!*.+(z|Z)' uncompress complete -f -o default -X '*.+(gz|GZ)' gzip complete -f -o default -X '!*.+(gz|GZ)' gunzip complete -f -o default -X '*.+(bz2|BZ2)' bzip2 complete -f -o default -X '!*.+(bz2|BZ2)' bunzip2 complete -f -o default -X '!*.+(zip|ZIP|z|Z|gz|GZ|bz2|BZ2)' extract # Documents - Postscript,pdf,dvi..... complete -f -o default -X '!*.+(ps|PS)' gs ghostview ps2pdf ps2ascii complete -f -o default -X \ '!*.+(dvi|DVI)' dvips dvipdf xdvi dviselect dvitype complete -f -o default -X '!*.+(pdf|PDF)' acroread pdf2ps complete -f -o default -X '!*.@(@(?(e)ps|?(E)PS|pdf|PDF)?\ (.gz|.GZ|.bz2|.BZ2|.Z))' gv ggv complete -f -o default -X '!*.texi*' makeinfo texi2dvi texi2html texi2pdf complete -f -o default -X '!*.tex' tex latex slitex complete -f -o default -X '!*.lyx' lyx complete -f -o default -X '!*.+(htm*|HTM*)' lynx html2ps complete -f -o default -X \ '!*.+(doc|DOC|xls|XLS|ppt|PPT|sx?|SX?|csv|CSV|od?|OD?|ott|OTT)' soffice # Multimedia complete -f -o default -X \ '!*.+(gif|GIF|jp*g|JP*G|bmp|BMP|xpm|XPM|png|PNG)' xv gimp ee gqview complete -f -o default -X '!*.+(mp3|MP3)' mpg123 mpg321 complete -f -o default -X '!*.+(ogg|OGG)' ogg123 complete -f -o default -X \ '!*.@(mp[23]|MP[23]|ogg|OGG|wav|WAV|pls|\ m3u|xm|mod|s[3t]m|it|mtm|ult|flac)' xmms complete -f -o default -X '!*.@(mp?(e)g|MP?(E)G|wma|avi|AVI|\ asf|vob|VOB|bin|dat|vcd|ps|pes|fli|viv|rm|ram|yuv|mov|MOV|qt|\ QT|wmv|mp3|MP3|ogg|OGG|ogm|OGM|mp4|MP4|wav|WAV|asx|ASX)' xine complete -f -o default -X '!*.pl' perl perl5 # This is a 'universal' completion function - it works when commands have #+ a so-called 'long options' mode , ie: 'ls --all' instead of 'ls -a' # Needs the '-o' option of grep #+ (try the commented-out version if not available). # First, remove '=' from completion word separators #+ (this will allow completions like 'ls --color=auto' to work correctly). COMP_WORDBREAKS=${COMP_WORDBREAKS/=/} _get_longopts() { #$1 --help | sed -e '/--/!d' -e 's/.*--\([^[:space:].,]*\).*/--\1/'| \ #grep ^"$2" |sort -u ; $1 --help | grep -o -e "--[^[:space:].,]*" | grep -e "$2" |sort -u } _longopts() { local cur cur=${COMP_WORDS[COMP_CWORD]} case "${cur:-*}" in -*) ;; *) return ;; esac case "$1" in \~*) eval cmd="$1" ;; *) cmd="$1" ;; esac COMPREPLY=( $(_get_longopts ${1} ${cur} ) ) } complete -o default -F _longopts configure bash complete -o default -F _longopts wget id info a2ps ls recode _tar() { local cur ext regex tar untar COMPREPLY=() cur=${COMP_WORDS[COMP_CWORD]} # If we want an option, return the possible long options. case "$cur" in -*) COMPREPLY=( $(_get_longopts $1 $cur ) ); return 0;; esac if [ $COMP_CWORD -eq 1 ]; then COMPREPLY=( $( compgen -W 'c t x u r d A' -- $cur ) ) return 0 fi case "${COMP_WORDS[1]}" in ?(-)c*f) COMPREPLY=( $( compgen -f $cur ) ) return 0 ;; +([^Izjy])f) ext='tar' regex=$ext ;; *z*f) ext='tar.gz' regex='t\(ar\.\)\(gz\|Z\)' ;; *[Ijy]*f) ext='t?(ar.)bz?(2)' regex='t\(ar\.\)bz2\?' ;; *) COMPREPLY=( $( compgen -f $cur ) ) return 0 ;; esac if [[ "$COMP_LINE" == tar*.$ext' '* ]]; then # Complete on files in tar file. # # Get name of tar file from command line. tar=$( echo "$COMP_LINE" | \ sed -e 's|^.* \([^ ]*'$regex'\) .*$|\1|' ) # Devise how to untar and list it. untar=t${COMP_WORDS[1]//[^Izjyf]/} COMPREPLY=( $( compgen -W "$( echo $( tar $untar $tar \ 2>/dev/null ) )" -- "$cur" ) ) return 0 else # File completion on relevant files. COMPREPLY=( $( compgen -G $cur\*.$ext ) ) fi return 0 } complete -F _tar -o default tar _make() { local mdef makef makef_dir="." makef_inc gcmd cur prev i; COMPREPLY=(); cur=${COMP_WORDS[COMP_CWORD]}; prev=${COMP_WORDS[COMP_CWORD-1]}; case "$prev" in -*f) COMPREPLY=($(compgen -f $cur )); return 0 ;; esac; case "$cur" in -*) COMPREPLY=($(_get_longopts $1 $cur )); return 0 ;; esac; # ... make reads # GNUmakefile, # then makefile # then Makefile ... if [ -f ${makef_dir}/GNUmakefile ]; then makef=${makef_dir}/GNUmakefile elif [ -f ${makef_dir}/makefile ]; then makef=${makef_dir}/makefile elif [ -f ${makef_dir}/Makefile ]; then makef=${makef_dir}/Makefile else makef=${makef_dir}/*.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 for tilde expansion eval makef=${COMP_WORDS[i+1]} break fi done [ ! -f $makef ] && return 0 # Deal with included Makefiles. makef_inc=$( grep -E '^-?include' $makef | sed -e "s,^.* ,"$makef_dir"/," ) for file in $makef_inc; do [ -f $file ] && makef="$makef $file" done # If we have a partial word to complete, restrict completions #+ to matches of that word. if [ -n "$cur" ]; then gcmd='grep "^$cur"' ; else gcmd=cat ; fi COMPREPLY=( $( awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ \ {split($1,A,/ /);for(i in A)print A[i]}' \ $makef 2>/dev/null | eval $gcmd )) } complete -F _make -X '+($*|*.[cho])' make gmake pmake _killall() { 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=( $( ps -u $USER -o comm | \ sed -e '1,1d' -e 's#[]\[]##g' -e 's#^.*/##'| \ awk '{if ($0 ~ /^'$cur'/) print $0}' )) return 0 } complete -F _killall killall killps # Local Variables: # mode:shell-script # sh-shell:bash # End: