.bashrc modifications are like nesting for developers. All I have right now is a few aliases and some PATH modifications. What's in yours?
Check out dotfiles.org. It is a place for sharing what you do in any of your "dotfiles".
My .bashrc is basically the default that comes with Ubuntu 8.04, with some added environment variables as needed for SQL Developer and SQLPLUS, among others. My .bash_aliases file gets longer by the day, mostly every combination of flags for ls, cdX aliases to go to specific points in my development tree, and some complex ssh tunnels so I don't have to remember which ports I need to open.
The big three things I put in every new bash file are the following:
export HISTCONTROL=erasedups
export HISTSIZE=10000
shopt -s histappend
It erases duplicate entries, cranks the size up to 10K entries (you can never have enough bash history, and tells the shell to append to the older history file, not overwrite it on exit.
Historically this has been the most important part of my bashrc. I use it to set proper paths, e.g. ~/inst/$SYS_BASE/bin.
case `uname` in
IRIX64)
SYS_BASE=sgi
;;
SunOS)
SYS_BASE=sun
;;
Linux)
SYS_BASE=linux
;;
Darwin)
SYS_BASE=mac
;;
*)
SYS_BASE=unknown
;;
esac
The most interesting line in my .bashrc would have to be the one for prefixing my prompt with the previous command's return code:
PS1='`_ret=$?; if test $_ret -ne 0; then echo "$_ret:"; set ?=$_ret; unset _ret; fi`\u@\h:\W\$ '
This way if the command returns a failure code, that code prefixes the next prompt, but if it succeeds nothing is printed. It maintains the $?
variable so you can use it in other conditionals.
ted@tohno:~$ true
ted@tohno:~$
ted@tohno:~$ false
1:ted@tohno:~$
This makes it easy to ensure that your programs have sensible return codes.
I add pwd to my prompt, aliases for deep directories I use a lot as well as wordy commands.
I also keep things like CVSROOT, MANPATH etc in my .profile. The other thing I've got in my .profile is a bail out for systems that don't have bash (a pretty regular thing in my life). The switch example above for setting base paths might be better off in a .profile instead of .bashrc for this reason.
Here is the function I use to color the prompt (cribbed from somewhere else online), I use a white background.
function prompt { local WHITE="\[\033[1;37m\]" local GREEN="\[\033[0;32m\]" local CYAN="\[\033[0;36m\]" local GRAY="\[\033[0;37m\]" local BLUE="\[\033[0;34m\]" local BLACK="\[\033[0;1m\]" local RESET='\[\033[00m\]' export PS1="${GREEN}\u${CYAN}@${BLUE}\h:${CYAN}\w${GREEN} >$ ${RESET}" }
I use bash but my login shell is set to sh and my .profile is set to start screen in reattach mode which starts bash. This way I can be disconnected at any time and not lose anything.
.profile
case $- in *i*)
bin_bash=`/usr/bin/which bash`
bin_screen=`/usr/bin/which screen`
# commands for interactive use only
if test -z $screen_lock
then
# commands for if no screen_lock is set
screen_lock=locked
export screen_lock
mesg n
if test -x $bin_screen
then
$bin_screen -xRR
if test $? -eq 0
then
# if we succeeded running screen then exit the shell (log out sh)
exit
else
if test $? -eq 1
then
# screen was suspended by the user
echo " !! ALERT !! You have suspended $bin_screen."
echo " !! ALERT !! Starting $bin_bash."
else
errcode=$?
echo " !! ERROR !! $bin_screen failed to exit cleanly."
echo " !! ERROR !! Error code: $errcode"
fi
fi
else
echo " !! ERROR !! $bin_screen cannot be executed."
fi
if test -x $bin_bash
then
$bin_bash
if test $? -eq 0
then
# if we succeeded running bash
exit
else
errcode=$?
echo " !! ERROR !! $bin_bash failed to exit cleanly."
echo " !! ERROR !! Your last command's Error code: $errcode"
fi
else
echo " !! ERROR !! $bin_bash cannot be executed."
fi
fi
esac
.screenrc
escape ^Xa
shell /usr/pkg/bin/bash
shelltitle '$ |bash'
startup_message off
nethack on
# This line works well in color and black and white.
hardstatus alwayslastline
"%{=r wb} %H %{c}%Y-%m-%d %{y}%0c %{= bw} %{kg}%-Lw%?
%?%{=r kg}%n%f* %t%?(%u)%?%{= kg}%+Lw%{bw} %{=r wb} %=::"
.bashrc
#invoked only on subshells:
bash_pref_file=bashrc
case $- in
*i*)
#The shell is interactive
if [ -f ~/.bash_login ]; then
source ~/.bash_login
fi
;;
*)
case $TERM in
xterm*)
TERM=xterm-16color
;;
esac
;;
esac
.bash_login
# $NetBSD: dot.profile,v 1.1.2.1 2000/10/20 17:00:53 tv Exp $
#:set syntax=sh
PATH=$HOME/bin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin:/usr/pkg/bin
PATH=${PATH}:/usr/pkg/sbin:/usr/games:/usr/local/bin:/usr/local/sbin
export PATH
EDITOR=vim
export EDITOR
EXINIT='set autoindent'
export EXINIT
PAGER=less
export PAGER
[email protected]
export REPLYTO
source ~/.aliases
# If this is an xterm set the title to user@host:dir
case $TERM in
xterm*)
#This '\[..\]' nonprints setting the title ]2, and the icon ]1 names of an xterm
export PS1='\[\e]2;\u@\h:\w\007\e]1;\h\007\]\u@\h:\w\$ '
TERM=xterm-16color
;;
screen*)
export PS1='\u@\h:\w\$ '
PROMPT_COMMAND='echo -n -e "\033k\033\134"'
;;
*)
export PS1='\u@\h:\w\$ '
;;
esac
.aliases
alias vi="vim"
alias lust="env TERM=vt220 ssh [email protected]"
alias pride="env TERM=vt220 ssh [email protected]"
alias fury="env TERM=vt220 ssh [email protected]"
alias slithy="env TERM=xterm-16color ssh [email protected]"
alias pine="echo USE MUTT!"
alias lambda="tf lambda.moo.mud.org 8888"
alias stripM="perl -pi -e 's/\r\n?/\n/g'"
alias nospam='cat ~/procmail.log | tail -n 30 > ~/procmail.log ;JTARG=`perl -e '"'"'my ($d,$n)=(\`date +%Y%m\`,\`formail -s echo <~/Mail/junk |wc -l\`);chomp($d,$n);$n=~s/ */-/;print "$ENV{HOME}/Mail/junk$d$n";'"'"'`; cp ~/Mail/junk $JTARG; bzip2 $JTARG;unset JTARG;rm ~/Mail/junk;'
function packspam () { SPAMTARG=`perl -e 'my $f="'$@'";chomp($f);$n=\`formail -s echo <$f |wc -l\`;chop($n);$n=~s/ */-/;$f=~s/-x$//;print $f.$n;'`; mv $@ $SPAMTARG; bzip2 $SPAMTARG; unset SPAMTARG; }
alias wl="for((;;)); do clear;w;sleep 20;done"
alias w="clear;w -n;echo;last -10"
alias new7='for d in 7 6 5 4 3 2 1; do find /home/communal/ -mtime $d -type f;done'
function m () { mesg n; mutt $@; mesg y; }
alias mutt=m
alias doing='mesg n;perl -ne '\''chomp;$0=$_'\'';mesg y'
I've always been a fancy profile whore, so I spent a lot of time getting this to look like I want it to. But since I got it the way I like it, I haven't changed it in 3 years.
- PS1 Definition File
- Alias Definition File
- Bash Profile (Basically Ubuntu Default)
- BashRC
Aside from the usual boring things, like adding directories to $PATH and $MANPATH, setting $EDITOR and history stuff mentioned above:
source /etc/bash_completion
..for shiney tab-completion (download here, completion for things like ssh hosts, so ssh mysi[tab] will complete ssh mysiteslongurl.example.com, and even seems to complete things like mencoder arguments)
source ~/.git-completion.bash
..completes git commands, branch names and such (it's in the contrib directory of git, or here)
alias gs="git status"
alias ga="git add"
alias gd="git diff"
alias gc="git commit"
alias gp="git push"
alias gu="git gui"
..shortened versions of common git commands, works with above tab completion
bind 'set match-hidden-files off'
..stops cd [tab][tab] showing .DS_Store and such files, unless you do .[tab][tab] - this means I can do cat [tab] to select the only file visible file in the directory (instead of always getting .DS_Store and the file)
bind "\C-e":clear-screen # bind ^e to clear
..ctrl+l is quite a stretch with one hand, ctrl+e is easier
alias cds="cd;clear"
..basically resets the terminal (changes to $HOME, clears screen)
alias cd..="cd .."
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
..allows typing ".." to go up a dir, "..." to go up two levels and so on, also corrects "cd.." which I seemed to type a lot
I also alias scr
to "screen -xU" and a bunch of OS X specific stuff, like
## OS X specific
# makes top use less CPU time
alias ltop='top -F -R -o cpu'
# Sleeps machine
alias macsleep='osascript -e "tell application \"Finder\" to sleep"'
# (un)lock dock
alias kdock="killall -9 Dock"
alias dock-lock="defaults write com.apple.dock contents-immutable -bool true; kdock"
alias dock-unlock="defaults write com.apple.dock contents-immutable -bool false; kdock"
# Laptop sleep/hibernate thingy. on == "deep sleep", off == "quick sleep"
alias hibernateon='sudo pmset -a hibernatemode 1'
alias hibernateoff='sudo pmset -a hibernatemode 0'
# make bash autocomplete with up arrow
bind '"\e[A":history-search-backward'
bind '"\e[B":history-search-forward'
# make tab cycle through commands instead of listing
bind '"\t":menu-complete'
I love this. The up arrow auto-completes function commands like magic.
I have aliases that help me with directory navigation and others that are specific for my project. In a sense, the command line becomes a DSL of sorts. Since I use Cygwin's Bash on Windows, I have a consistent shell across all machines. I can barely work on someone else's machine without my aliases!
I've blogged on some of the generic stuff here. I find them really useful and some (but not all) of my teammates pick it up on every project on which I work.
Aliases
# Typing "rm -f *~" is too risky
alias cleanup='rm -f *~; true'
alias vibashrc='vi ~/.bashrc; . ~/.bashrc'
alias sr='ssh -l root'
History
# Ignore lines w/ ls, cd, ...
export HISTIGNORE="ls:cd:[bf]g:exit"
# Ignore lines which begin with a space character and duplicate lines
export HISTCONTROL="ignoreboth"
Host completion: when typing @<TAB>
# Use our own file instead of /etc/hosts
export HOSTFILE="${HOME}/.hosts"
# Collect host names from SSH known hosts file
sed 's/\(.*\),.*/\1/; s/ .*//' ${HOME}/.ssh/known_hosts | sort > ${HOME}/.hosts
Prompt
# Check if we are inside screen
if [ -n "${STY#*.}" ]; then
export PS1='\[\033[01;34m\][\[\033[01;33m\]\u@\h-screen($WINDOW)\[\033[01;34m\]\W][\[\033[01;31m\]\j\[\033[01;34m\]]\$ \[\033[00m\]'
else
export PS1='\[\033[01;34m\][\[\033[01;35m\]\u@\h\[\033[01;34m\] \W][\[\033[01;31m\]\j\[\033[01;34m\]]\$ \[\033[00m\]'
fi
my ~/.bashrc file is very short; it has only the following in it:
if [ -d ~/.bashrc.d ]; then
for file in $(/bin/ls ~/.bashrc.d/); do
. "~/.bashrc.d/$file";
done
fi
that lets me separate everything out into much more manageable pieces, instead of having aliases mixed in with environment variables mixed in with my prompt customizations.
Truncate long lines
function ...() {
local -i n;
let n=$(tput cols)/2-3;
sed -re "s/^(.{$n}).*(.{$n})$/\1 ... \2/"
}
use:
$ command-that-produce-long-line-output | ...
this is a short line
and this is a very very very very very ... very very very very very long line
and this is another very very very ver ... very very very very very long line
this line is not long enough to be truncated.
cd ...
function cd () {
local -ri n=${#*};
if [ $n -eq 0 -o -d "${!n}" -o "${!n}" == "-" ]; then
builtin cd "$@";
else
local e="s:\.\.\.:../..:g";
builtin cd "${@:1:$n-1}" $(sed -e$e -e$e -e$e <<< "${!n}");
fi
}
use
cd ... # cd ../..
cd .... # cd ../../..
cd ...../foo # cd ../../../../foo
etc...
I usethis for my ANSI colored prompt including username and machine name: LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:.cmd=01;32:.exe=01;32:.com=01;32:.btm=01;32:.bat=01;32:.sh=00;32:.csh=00;32:.tar=01;31:.tgz=01;31:.arj=01;31:.taz=01;31:.lzh=01;31:.zip=01;31:.z=01;31:.Z=01;31:.gz=01;31:.bz2=01;31:.jpg=01;35:.gif=01;35:.bmp=01;35:.xbm=01;35:.xpm=01;35:*.tif=00;35:';
export LS_COLORS;
C_RED="\[\033[0;31m\]"
C_GREEN="\[\033[0;32m\]"
C_LIGHT_GRAY="\[\033[0;37m\]"
C_RESET="\[\033[0m\]"
C_BROWN="\[\033[0;33m\]"
C_BLUE="\[\033[0;34m\]"
C_PURPLE="\[\033[0;35m\]"
C_CYAN="\[\033[0;36m\] "
C_GRAY="\[\033[1;30m\]"
C_WHITE="\[\033[1;37m\]"
C_YELLOW="\[\033[1;33m\]"
C_LIGHT_BLUE="\[\033[1;34m\]"
C_LIGHT_CYAN="\[\033[1;36m\]"
C_LIGHT_PURPLE="\[\033[1;35m\]"
C_LIGHT_RED="\[\033[1; 31m\]"
C_LIGHT_GREEN="\[\033[1;32m\]"
export PS1="$C_LIGHT_GREEN[\u@\H $C_LIGHT_BLUE\w] $C_RESET"
I have a git repository for stuff I want on all my shells, where among other files, I have a .bash_shared file that I import from .bashrc.
Exact file name search:
alias f='find . -type f -name'
Fuzzy filename search (ff string matches *string*):
ff () {
find . -type f -iname '*'"$@"'*' ;
}
ps aux | grep foo
without listing the grep command:
psg () {
FIRST=`echo $1 | sed -e 's/^\(.\).*/\1/'`
REST=`echo $1 | sed -e 's/^.\(.*\)/\1/'`
ps aux | grep "[$FIRST]$REST"
}
My fingers hate moving, so here's a couple of my favorite aliases, based on some of my most-commonly-used commands:
alias ff='ls'
alias fff='ls -al'
alias cdd='cd ..'
mkdirr () { mkdir "$1" && cd "$1"; }
I don't have to move my hands from the home row to list a directory's contents, and I can just repeat the last letter of my command when I do a very common task like moving up a directory or creating a directory and changing to it at the same time.
if [ x$TERM = xxterm ] || [ x$TERM = xxterm-color ] ; then
export PS1='\[\e]0;\u@\h:\w/\007\]\[\e[1;32m\]:;\[\e[0m\] '
else
export PS1=":; "
end
Having :;
as the prompt means I can triple-click a previous command to select the entire line and middle-button-paste it straight into another window (e.g. if I was not on the machine I thought I was on, or I want to try it in a different directory) without having to delete a $ or a # or a % on the front.
(The extra gubbins in the xterm case is just to put username, hostname, cwd in the window title bar)
How does it work? :
is the "null command"; ;
is the command separator