Shell recipes
Jumping to temporary directories in zsh and bash
Keeping a home directory uncluttered is tough. I often create lists, scripts, or one-off programs I think I may need to refer back to later, but putting them all in a single place quickly becomes unmanageable.
With this function, when I type t
, my shell sends me to a $HOME/temp/YYYYMMDD
directory for the current date, creating the directory if it doesn't exist. To jump to yesterday's directory
or the directory from a week ago, I can run t 1
or t 7
respectively. For
longer-term temporary things, I can run t foo
to go to $HOME/temp/foo
. If I just
want to print the directory's name instead of moving to it (suppose that I want to redirect the output from
a command to a file), I can run tp
or tp foo
(the directory will be created first
if it doesn't exist).
# switch to temporary directories
temp_dir() {
local gothere=$1
local base=$HOME/temp
local create=1
if test "$2"; then
if echo "$2" | egrep -q '^[0-9]+$' && test $2 -gt 0; then
local dir=$base/$(date -d "$2 days ago" +%Y%m%d)
local create=0
else
local dir="$base/$2"
fi
else
local dir=$base/$(date +%Y%m%d)
fi
if [[ $create == 1 ]] && test \! -e "$dir"; then
mkdir -p "$dir"
fi
if [[ $gothere == 1 ]]; then
cd $dir
else
echo $dir
fi
}
t() { temp_dir 1 $1; }
tp() { temp_dir 0 $1; }
Setting a custom prompt
This one isn't terribly exciting, but it served me well for the many years that I was using bash:
[user@host][/usr/share]$ ls -la
END="\[\033[0m\]"
BLUE="\[\033[0;34m\]"
YELLOW="\[\033[0;33m\]"
RED="\[\033[0;31m\]"
GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
L_GRAY="\[\033[0;37m\]"
D_GRAY="\[\033[1;30m\]"
L_BLUE="\[\033[1;34m\]"
L_GREEN="\[\033[1;32m\]"
L_CYAN="\[\033[1;36m\]"
L_RED="\[\033[1;31m\]"
L_PURPLE="\[\033[1;35m\]"
WHITE="\[\033[1;37m\]"
PS1="$D_GRAY[$L_GRAY\u$D_GRAY@$L_GRAY\h$D_GRAY][$L_GRAY\w$D_GRAY]$L_GRAY$ $END"
I'm using zsh instead of bash now, and my prompt looks like this:
[/usr/share] host% ls -la
autoload colors zsh/terminfo
if [[ "$terminfo[colors]" -ge 8 ]]; then
colors
fi
for color in BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE; do
eval PR_LIGHT_$color='%{$terminfo[bold]$fg[${(L)color}]%}'
eval PR_$color='%{$fg[${(L)color}]%}'
(( count = $count + 1 ))
done
PR_PLAIN="%{$terminfo[sgr0]%}"
PROMPT="$PR_WHITE%m%# $PR_PLAIN"
RPROMPT="${PR_LIGHT_BLACK}[$PR_PLAIN$PR_WHITE%~${PR_LIGHT_BLACK}]$PR_PLAIN"
Setting the window title in bash
When I have many terminal windows open, it's nice to be able to see which is which without having to remember their positions or check their contents.
By echoing special sequences of characters, it's possible to instruct xterm to change its icon name or window title. See the xterm Title HOWTO and the Bash Prompt HOWTO for more details.
When I'm using a terminal emulator that supports it, I can type n foo
to change a window's name
to foo. Typing n
without any parameters switches the title back to the default, user@host.
When I use SSH to connect to another host, the window's name is updated appropriately.
Note: If you use a terminal emulator other than xterm, you'll need to update the if
statement at the top of this code block. Run echo $TERM
to see which value you need to use.
if [ "$TERM" = "xterm" ] || [ "$TERM" = "screen" ]; then
# make "n" echo escape characters to change xterm's name
n() {
if [ -n "$*" ]; then
PROMPT_COMMAND="echo -ne \"\033]2;$*\007\""
else
PROMPT_COMMAND='echo -ne "\033]2;`whoami`@`hostname`\007"'
fi
}
n
alias_ssh () { echo -ne "\033]2;$*\007"; "ssh" $*; }
alias ssh=alias_ssh
fi
Custom colors in xterm
This really doesn't have anything to do with shells, but that won't stop me from including it. I put the
following in my $HOME/.Xresources
file to make xterm's colors a bit more pleasing:
XTerm.*background: black
XTerm.*foreground: white
XTerm.*boldMode: false
XTerm.*color0: #000000
XTerm.*color1: #9e1828
XTerm.*color2: #4f874f
XTerm.*color3: #968a38
XTerm.*color4: #5d5da0
XTerm.*color5: #963c59
XTerm.*color6: #418179
XTerm.*color7: gray
XTerm.*color8: gray40
XTerm.*color9: #cf6171
XTerm.*color10: #c5f779
XTerm.*color11: #fff796
XTerm.*color12: #4186be
XTerm.*color13: #cf9ebe
XTerm.*color14: #71bebe
XTerm.*color15: white
I use rxvt-unicode instead of xterm now. To
get the same effect there, I replaced the XTerm.*
in the above lines with URxvt.
and replaced the boldMode
line with a URxvt.boldFont
line specifying the same font
as my URxvt.font
.