| 1 | ### -*-bash-*- |
| 2 | ### |
| 3 | ### Bash session things |
| 4 | |
| 5 | ## Only do this if we haven't done it before. (Note that this guard isn't |
| 6 | ## exported, so subshells will need to make their own arrangements.) |
| 7 | if [ -z "$__mdw_bashrc" ]; then |
| 8 | __mdw_bashrc=done |
| 9 | |
| 10 | ## If we've not run the main profile yet, we should do that first. It sets |
| 11 | ## up things we rely on. Also, if there's a system script, we should run |
| 12 | ## that too. |
| 13 | [ -z "$__mdw_profile" -a -r $HOME/.bash_profile ] && . $HOME/.bash_profile |
| 14 | [ -r /etc/bashrc ] && . /etc/bashrc |
| 15 | |
| 16 | ## Set the temporary directory again. (If we've switched users, we'll want a |
| 17 | ## different temporary directory.) |
| 18 | [ "${TMPDIR+yes}" ] || eval `tmpdir -b` |
| 19 | |
| 20 | ###-------------------------------------------------------------------------- |
| 21 | ### Prompt hacking. |
| 22 | |
| 23 | ## Only bother if the shell is interactive. |
| 24 | if [ -t 0 ]; then |
| 25 | |
| 26 | ## Fancy highlighting in some terminals. |
| 27 | marker=${STY+'\[\ek\e\\\]'} |
| 28 | case "$TERM" in |
| 29 | linux*|screen*|xterm*|vt100*|eterm*) |
| 30 | case "$(tput bold)" in |
| 31 | "") bold="\[$(tput md)\]" unbold="\[$(tput me)\]" ;; |
| 32 | *) bold="\[$(tput bold)\]" unbold="\[$(tput sgr0)\]" ;; |
| 33 | esac |
| 34 | nl="\[\r\]" |
| 35 | ;; |
| 36 | *) |
| 37 | bold='' unbold='' nl='' ;; |
| 38 | esac |
| 39 | |
| 40 | ## Choose the right delimiters. Highlight root prompts specially; |
| 41 | ## highlight when I'm running as some other user. Highlight when this |
| 42 | ## isn't the outermost shell on the terminal. |
| 43 | if (( EUID == 0 )); then |
| 44 | left=`echo « | iconv -f UTF-8 -t //translit` |
| 45 | right=`echo » | iconv -f UTF-8 -t //translit` |
| 46 | else |
| 47 | case $USER in |
| 48 | mdw|mwooding) u="" left="[" right="]" ;; |
| 49 | *) u="\\u@" left="{" right="}" ;; |
| 50 | esac |
| 51 | if [ "$__mdw_tty" = "`tty`" ]; then |
| 52 | left="<" right=">" |
| 53 | else |
| 54 | export __mdw_tty="`tty`" |
| 55 | fi |
| 56 | fi |
| 57 | |
| 58 | ## If this session is insecure then highlight that. |
| 59 | if [ -z "$SSH_CLIENT" ] && |
| 60 | [ "$__mdw_sechost" != "`hostname`" ] |
| 61 | then |
| 62 | sec_l='(' sec_r=')' |
| 63 | fi |
| 64 | |
| 65 | ## Build the prompt string. |
| 66 | PS1="$nl$bold$left$sec_l$u\\h$sec_r \\w$marker$right$unbold" |
| 67 | PS2="$PS1 $bold>$unbold " |
| 68 | |
| 69 | fi |
| 70 | |
| 71 | ###-------------------------------------------------------------------------- |
| 72 | ### Other shell tweaking. |
| 73 | |
| 74 | ## Random shell tweaks. |
| 75 | notify=1 |
| 76 | set -b |
| 77 | shopt -u cdable_vars |
| 78 | shopt -s cdspell |
| 79 | shopt -s checkhash |
| 80 | shopt -s checkwinsize |
| 81 | shopt -s cmdhist |
| 82 | shopt -u dotglob |
| 83 | shopt -s expand_aliases |
| 84 | shopt -s extglob |
| 85 | shopt -s globstar |
| 86 | shopt -s gnu_errfmt |
| 87 | shopt -s histappend |
| 88 | shopt -s histreedit |
| 89 | shopt -u histverify |
| 90 | shopt -s hostcomplete |
| 91 | shopt -s huponexit |
| 92 | shopt -s interactive_comments |
| 93 | shopt -s lithist |
| 94 | shopt -u mailwarn |
| 95 | shopt -u nocaseglob |
| 96 | shopt -u nullglob |
| 97 | shopt -s promptvars |
| 98 | shopt -u shift_verbose |
| 99 | shopt -s sourcepath |
| 100 | HISTCONTROL=ignorespace:erasedups |
| 101 | |
| 102 | ## Some handy aliases. |
| 103 | alias cx='chmod a+x' |
| 104 | alias which="command -v" |
| 105 | alias rc="rc -l" |
| 106 | alias ssync="rsync -e ssh" |
| 107 | rootly () { |
| 108 | case $# in 0) set -- "${SHELL-/bin/sh}" ;; esac |
| 109 | $__MDW_ROOTLY "$@" |
| 110 | } |
| 111 | alias r=rootly |
| 112 | alias re="rootly $EDITOR" |
| 113 | alias pstree="pstree -hl" |
| 114 | alias cdtmp='cd ${TMPDIR-/tmp}' |
| 115 | alias pushtmp='pushd ${TMPDIR-/tmp}' |
| 116 | alias e="$EDITOR" |
| 117 | alias svn="svnwrap svn" |
| 118 | alias @="ssh" |
| 119 | |
| 120 | ## Completion. |
| 121 | [ -r /etc/bash_completion ] && . /etc/bash_completion |
| 122 | [ -r $HOME/.bash_completion ] && . $HOME/.bash_completion |
| 123 | |
| 124 | ###-------------------------------------------------------------------------- |
| 125 | ### Colour output. |
| 126 | |
| 127 | ## Arrange for `ls' output to be in colour. |
| 128 | if [ -x /usr/bin/dircolors -o -x /usr/local/bin/dircolors ]; then |
| 129 | eval `dircolors -b ~/.dircolors` |
| 130 | else |
| 131 | unset LS_COLORS |
| 132 | fi |
| 133 | |
| 134 | ls () { |
| 135 | if [ -t 1 ]; then |
| 136 | command ls $LS_OPTIONS ${LS_COLORS+--color=auto} "$@" |
| 137 | else |
| 138 | command ls "$@" |
| 139 | fi |
| 140 | } |
| 141 | |
| 142 | ## Arrange for `grep' output to be in colour. |
| 143 | export GREP_COLORS="mt=01;31:ms=01;31:mc=031;31:fn=36:ln=36:bn=36:se=34" |
| 144 | |
| 145 | greplike () { |
| 146 | declare grep=$1; shift |
| 147 | if [ -t 1 ]; then |
| 148 | command $grep ${GREP_COLORS+--color=always} "$@" | mdw-pager |
| 149 | else |
| 150 | command $grep "$@" |
| 151 | fi |
| 152 | } |
| 153 | alias grep="greplike grep" |
| 154 | alias egrep="greplike egrep" |
| 155 | alias fgrep="greplike fgrep" |
| 156 | alias zgrep="greplike zgrep" |
| 157 | |
| 158 | ## Turn off pagers inside Emacs shell buffers. |
| 159 | case "$INSIDE_EMACS" in |
| 160 | 22.*,comint) export PAGER=cat ;; |
| 161 | esac |
| 162 | |
| 163 | ###-------------------------------------------------------------------------- |
| 164 | ### More complicated shell functions. |
| 165 | |
| 166 | ## xt [@HOST] XTERM-ARGS |
| 167 | ## |
| 168 | ## Open a terminal, maybe on a remote host. |
| 169 | xt () { |
| 170 | case "$1" in |
| 171 | @*) |
| 172 | local remote=${1#@} title |
| 173 | shift |
| 174 | if [ $# -gt 0 ]; then |
| 175 | title="xterm [$remote] $1" |
| 176 | else |
| 177 | title="xterm [$remote]" |
| 178 | fi |
| 179 | (xterm -title "$title" -e ssh $remote "$@" &) |
| 180 | ;; |
| 181 | *) |
| 182 | (xterm "$@" &) |
| 183 | ;; |
| 184 | esac |
| 185 | } |
| 186 | |
| 187 | ## core [y|n] |
| 188 | ## |
| 189 | ## Tweak core dumps on and off, or show the current status. |
| 190 | core () { |
| 191 | case "x$1" in |
| 192 | xon|xy|xyes) ulimit -Sc `ulimit -Hc` ;; |
| 193 | xoff|xn|xno) ulimit -Sc 0 ;; |
| 194 | x) |
| 195 | local l=`ulimit -Sc` |
| 196 | case $l in |
| 197 | 0) echo "Core dumps disabled" ;; |
| 198 | unlimited) echo "Core dumps enabled" ;; |
| 199 | *) echo "Core dump limit is $l blocks" ;; |
| 200 | esac |
| 201 | ;; |
| 202 | *) |
| 203 | echo >&2 "usage: core [y|n]" |
| 204 | return 1 |
| 205 | ;; |
| 206 | esac |
| 207 | } |
| 208 | |
| 209 | ## world [NAME] |
| 210 | ## |
| 211 | ## Set current security world to NAME. With no NAME, print the currently |
| 212 | ## selected world. |
| 213 | world () { |
| 214 | local nfast=${NFAST_HOME-/opt/nfast} |
| 215 | local kmdata |
| 216 | case "$#" in |
| 217 | 0) |
| 218 | echo "${NFAST_KMDATA#$nfast/kmdata-}" |
| 219 | ;; |
| 220 | *) |
| 221 | if [ -d "$1" ]; then |
| 222 | kmdata=$1 |
| 223 | elif [ -d "$nfast/kmdata-$1" ]; then |
| 224 | kmdata=$nfast/kmdata-$1 |
| 225 | else |
| 226 | echo >&2 "world: can't find world $1" |
| 227 | return 1 |
| 228 | fi |
| 229 | shift |
| 230 | case "$#" in |
| 231 | 0) export NFAST_KMDATA=$kmdata ;; |
| 232 | *) "$@" ;; |
| 233 | esac |
| 234 | ;; |
| 235 | esac |
| 236 | } |
| 237 | |
| 238 | ## Fix `man' under Slowaris. |
| 239 | case "$MACHTYPE" in |
| 240 | *solaris*) |
| 241 | man () { |
| 242 | declare -i i=0 |
| 243 | declare arg |
| 244 | declare -a man |
| 245 | for arg; do |
| 246 | case "$arg" in [0-9]*) man[i+=1]="-s" ;; esac |
| 247 | man[i+=1]="$arg" |
| 248 | done |
| 249 | command man "${man[@]}" |
| 250 | } |
| 251 | ;; |
| 252 | esac |
| 253 | |
| 254 | ###-------------------------------------------------------------------------- |
| 255 | ### Path hacks. |
| 256 | |
| 257 | ## path-add [VAR] DIR |
| 258 | ## |
| 259 | ## Add DIR to the beginning of PATH-like variable VAR (defaults to PATH) if |
| 260 | ## it's not there already. |
| 261 | path-add () { |
| 262 | local pathvar export dir val |
| 263 | case $# in |
| 264 | 1) pathvar=PATH dir=$1 export="export PATH";; |
| 265 | 2) pathvar=$1 dir=$2 export=:;; |
| 266 | *) echo >&2 "Usage: $0 [VAR] DIR";; |
| 267 | esac |
| 268 | eval "val=\$$pathvar" |
| 269 | case ":$val:" in |
| 270 | *:"$dir":*) ;; |
| 271 | *) val=$dir:$val ;; |
| 272 | esac |
| 273 | eval "$pathvar=\$val" |
| 274 | $export |
| 275 | } |
| 276 | |
| 277 | ## path-remove [VAR] DIR |
| 278 | ## |
| 279 | ## Remove DIR from PATH-like variable VAR (defaults to PATH); it's not an |
| 280 | ## error if DIR isn't in VAR. |
| 281 | path-remove () { |
| 282 | local pathvar export dir val |
| 283 | case $# in |
| 284 | 1) pathvar=PATH dir=$1 export="export PATH";; |
| 285 | 2) pathvar=$1 dir=$2 export=:;; |
| 286 | *) echo >&2 "Usage: $0 [VAR] DIR";; |
| 287 | esac |
| 288 | eval "val=\$$pathvar" |
| 289 | case ":$val:" in |
| 290 | :"$dir":) val= ;; |
| 291 | :"$dir":*) val=${val#$dir:} ;; |
| 292 | *:"$dir":) val=${val%:$dir} ;; |
| 293 | *:"$dir":*) val=${val/:$dir:/:} ;; |
| 294 | esac |
| 295 | eval "$pathvar=\$val" |
| 296 | $export |
| 297 | } |
| 298 | |
| 299 | ## pathhack [-f] +HACK|-HACK... |
| 300 | ## |
| 301 | ## Each HACK refers to a subdirectory of `~/bin/hacks'. A hack name preceded |
| 302 | ## by `+' adds the directory to the PATH; a `-' removes. Adding a hack |
| 303 | ## that's already on the PATH doesn't do anything unless `-f' is set, in |
| 304 | ## which case it gets moved to the beginning. With no arguments, print the |
| 305 | ## currently installed hacks. |
| 306 | pathhack () { |
| 307 | if [ $# -eq 0 ]; then |
| 308 | local IFS=: |
| 309 | for e in $PATH; do |
| 310 | case "$e" in |
| 311 | "$HOME/bin/hacks/"*) |
| 312 | echo ${e#$HOME/bin/hacks/} |
| 313 | ;; |
| 314 | esac |
| 315 | done |
| 316 | return |
| 317 | fi |
| 318 | local force=nil |
| 319 | local path=$PATH |
| 320 | while [ $# -gt 0 ]; do |
| 321 | arg=$1 |
| 322 | case "$arg" in |
| 323 | -f | --force) |
| 324 | force=t |
| 325 | shift |
| 326 | continue |
| 327 | ;; |
| 328 | --) |
| 329 | shift |
| 330 | break |
| 331 | ;; |
| 332 | [-+]*) |
| 333 | ;; |
| 334 | *) |
| 335 | break |
| 336 | ;; |
| 337 | esac |
| 338 | hack=${arg#[+-]} |
| 339 | dir=$HOME/bin/hacks/$hack |
| 340 | [ -d "$dir" ] || { |
| 341 | echo "$0: path hack $hack not found" |
| 342 | return 1 |
| 343 | } |
| 344 | case "$arg,$force,:$PATH:" in |
| 345 | -*,*,*:"$dir":*) |
| 346 | path-remove path "$dir" |
| 347 | ;; |
| 348 | +*,t,*:"$dir":*) |
| 349 | path-remove path "$dir" |
| 350 | path-add path "$dir" |
| 351 | ;; |
| 352 | +*,nil,*:"$dir":*) |
| 353 | ;; |
| 354 | +*,*) |
| 355 | path-add path "$dir" |
| 356 | ;; |
| 357 | esac |
| 358 | shift |
| 359 | done |
| 360 | if [ $# -eq 0 ]; then |
| 361 | PATH=$path |
| 362 | export PATH |
| 363 | else |
| 364 | PATH=$path "$@" |
| 365 | fi |
| 366 | } |
| 367 | |
| 368 | ###-------------------------------------------------------------------------- |
| 369 | ### Finishing touches. |
| 370 | |
| 371 | ## For `root' use -- some simple molly-guards. |
| 372 | if (( UID == 0 )); then |
| 373 | alias rm='rm -i' cp='cp -i' mv='mv -i' |
| 374 | set -o noclobber |
| 375 | fi |
| 376 | |
| 377 | ## Run any local hooks. |
| 378 | [ -f "$HOME/.bashrc-local" ] && . "$HOME/.bashrc-local" |
| 379 | |
| 380 | ## Close the `__mdw_bashrc' guard. |
| 381 | fi |
| 382 | |
| 383 | ###----- That's all, folks -------------------------------------------------- |