Today, I came across Advanced Bash-Scripting Guide, which I found to be extremely useful. (For those who love techy bash/ssh stuff, it makes for good bedtime reading.) From it, I created my .bash_profile
file.
For those who don't know anything about SSH, when you log into Hostgator SSH, you get something like this:
Very DOS-ish. Old School. But fast nonetheless.
If you change directories into public_html or whatever, then you get something like this:
Really!? Did it work? What happened? As I always say, "No news is good news." However, the .bash_profile
that I used to create my .bash_profile
is expansive and contains a lot of nifty helps, explanations, and functions. Take a look at it and try it out!
I broke it up into various copy-paste sections. See below for the full file.
# =============================================================== # | |
# | |
# PERSONAL $HOME/.bashrc FILE for bash-3.0 (or later) | |
# By Emmanuel Rouat [no-email] | |
# http://tldp.org/LDP/abs/html/sample-bashrc.html | |
# | |
# 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 |
#------------------------------------------------------------- | |
# Automatically load .bashrc | |
#------------------------------------------------------------- | |
[[ -s ~/.bashrc ]] && source ~/.bashrc | |
#------------------------------------------------------------- | |
# Source global definitions (if any) | |
#------------------------------------------------------------- | |
if [ -f /etc/bashrc ]; then | |
. /etc/bashrc # --> Read /etc/bashrc, if present. | |
fi |
#------------------------------------------------------------- | |
# Some settings | |
#------------------------------------------------------------- | |
# DEBUGGING | |
#set -o nounset, same as -u | |
# Treat unset variables and parameters other than the special parameters ‘@’ or ‘*’ as an error | |
# when performing parameter expansion. An error message will be written to the standard error, | |
# and a non-interactive shell will exit. | |
#set -o xtrace, same as -x | |
# Print a trace of simple commands, for commands, case commands, select commands, and arithmetic | |
# for commands and their arguments or associated word lists after they are expanded and before | |
# they are executed. The value of the PS4 variable is expanded and the resultant value is printed | |
# before the command and its expanded arguments. | |
# Set debugging options as alias | |
alias debug="set -o nounset; set -o xtrace" | |
ulimit -S -c 0 # Don't want coredumps. | |
# set -o notify, same as -b | |
# Cause the status of terminated background jobs to be reported immediately, | |
# rather than before printing the next primary prompt. | |
set -o notify | |
# set -o noclobber, same as -C | |
# Prevent output redirection using ‘>’, ‘>&’, and ‘<>’ from overwriting existing files. | |
set -o noclobber | |
# set -o ignoreeof | |
# An interactive shell will not exit upon reading EOF. | |
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. |
#------------------------------------------------------------- | |
# 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' ... |
#------------------------------------------------------------- | |
# Hostgator Aliases | |
#------------------------------------------------------------- | |
# PHP 5.3 | |
#alias php='/opt/php53/bin/php' | |
# PHP 5.3 | |
alias php='/opt/php54/bin/php' |
#------------------------------------------------------------- | |
# 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= "$@" ;} |
#------------------------------------------------------------- | |
# 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 | |
} |
#------------------------------------------------------------- | |
# 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"} | |
} | |
# alias for my_ip | |
function myip() { my_ip; } | |
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; | |
} |
#========================================================================= | |
# | |
# 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: |
Full .bash_profile
# =============================================================== # | |
# | |
# 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 | |
#------------------------------------------------------------- | |
# Automatically load .bashrc | |
#------------------------------------------------------------- | |
[[ -s ~/.bashrc ]] && source ~/.bashrc | |
#------------------------------------------------------------- | |
# 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' ... | |
#------------------------------------------------------------- | |
# 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"} | |
} | |
# alias for my_ip | |
function myip() { my_ip; } | |
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; | |
} | |
#------------------------------------------------------------- | |
# 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: |
Take a look and see what you think.
Leave a Reply