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