├── README.md └── bashrc_dispatch /README.md: -------------------------------------------------------------------------------- 1 | bashrc\_dispatch 2 | ================= 3 | 4 | **Different bash configurations for Linux vs OSX, interactive vs batch** 5 | 6 | (For related discussion see [hackernews](http://news.ycombinator.com/item?id=4369485)) 7 | 8 | Are you tired of trying to remember what `.bashrc` does vs `.bash_profile` 9 | vs `.profile`? 10 | 11 | Are you tired of trying to remember how Darwin (Mac OS X) treats them 12 | differently from Linux? 13 | 14 | Are you tired of not having your `~/.bash*` stuff work the way you expect? 15 | 16 | 17 | Setup / Usage 18 | -------------- 19 | 20 | Symlink all of the following files to `bashrc_dispatch` (after reading warnings 21 | below): 22 | 23 | * `~/.bashrc` 24 | * `~/.bash_profile` 25 | * `~/.profile` (only if your scripts are all 'sh' compatible- otherwise get rid of it altogether) 26 | * `~/.bash_login` 27 | 28 | And then you can use these instead: 29 | 30 | * `~/.bashrc_once`: sourced at least once, and in most circumstances only once- before anything else. 31 | * `~/.bashrc_all`: sourced on every bash instantiation 32 | * `~/.bashrc_script`: sourced only when non-interactive / batch 33 | * `~/.bashrc_interactive`: the one you'll probably fill up (*mutually exclusive* with `~/.bashrc_script`) 34 | * `~/.bashrc_login`: sourced only when an interactive shell is also a login. 35 | 36 | To reiterate, 37 | 38 | 1. `~/.bashrc_once` will be run before any of the others, but then won't be run 39 | again (ideally). 40 | 2. `~/.bashrc_all` will run next, and will be run on _every_ bash invocation. 41 | (so keep it light) 42 | 2. Then either `~/.bashrc_script` *or* `~/.bashrc_interactive` will be run 43 | next depending on whether or not the bash invocation is interactive. 44 | 3. Finally, sometimes, like when you first ssh into a machine or often when 45 | opening a new terminal window on a mac, the `~/.bashrc_login` will be run 46 | after the `~/.bash_interactive`. So `~/.bashrc_login` is the one where 47 | you'd echo a banner or whatever. For things like setting the PATH, use 48 | `.bashrc_once` instead. 49 | 50 | 51 | Exported Stuff 52 | -------------- 53 | 54 | In addition to the dispatching, you'll forever have the following available: 55 | 56 | * `$SHELL_PLATFORM` (either `LINUX`, `OSX`, `BSD`, `CYGWIN` or `OTHER`), 57 | * `shell_is_linux`, 58 | * `shell_is_osx`, 59 | * `shell_is_cygwin`, 60 | * `shell_is_interactive`, 61 | * `shell_is_script`. 62 | 63 | The functions are meant for clean conditionals in your new `~/.bashrc_*` 64 | scripts like: 65 | 66 | $ shell_is_linux && echo 'leenux!' 67 | 68 | or something like: 69 | 70 | $ if shell_is_interactive ; then echo 'interact' ; fi 71 | 72 | Warnings 73 | --------- 74 | 75 | * Obviously don't simply blow away your existing startup scripts if they have 76 | anything in them- you'll need their content to populate the new `bashrc_*` 77 | stuff. 78 | 79 | * If you symlink `~/.profile` to this script you may be fine, but since it 80 | sometimes gets sourced by a true `sh` command and the script currently has 81 | some bash-only stuff, it might not. Specifically, remove the symlink to 82 | `~/.profile` if anything starts acting strange on startup or xwindows-based 83 | login. 84 | 85 | * Be very careful what you put in `.bashrc_all` and `.bashrc_script` - it may 86 | slow the system down. I put them there for conceptual completeness- that 87 | doesn't mean you have to use them (: 88 | 89 | Additional Configuration 90 | ------------------------- 91 | 92 | There are few knobs you can turn to make `bashrc_dispatch` behave as you prefer. 93 | 94 | * `EXPORT_FUNCTIONS`: set it to `false` to disable the export of 95 | `$SHELL_PLATFORM` and all the `shell_is_*` functions and avoid polluting all 96 | the other shells' environments. 97 | 98 | * Inside `bashrc_dispatch` you can change `PRF=` to a location other than 99 | `${HOME}/.` to have it look for your new `bashrc_*` scripts somewhere else. 100 | 101 | * In general, modify your `bashrc_dispatch` script as much as you need to. 102 | You'll see there's not a lot of code there. Much less code then there are 103 | comments in this readme. Please share a patch if you like your modification. 104 | 105 | Authors 106 | ------- 107 | 108 | * Joseph Wecker 109 | * Gioele Barabucci (fixes and optimizations) 110 | 111 | 112 | Development 113 | ----------- 114 | 115 | Code 116 | : 117 | 118 | Report issues 119 | : 120 | 121 | 122 | License 123 | ------- 124 | 125 | This is free software released into the public domain. 126 | 127 | -------------------------------------------------------------------------------- /bashrc_dispatch: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Launch different bash configuration for Linux vs OSX, interactive vs batch 4 | # 5 | # More info at https://github.com/josephwecker/bashrc_dispatch 6 | # 7 | # License: Public Domain. 8 | # Author: Joseph Wecker, 2012 9 | 10 | # Configuration 11 | # ------------- 12 | # 13 | # EXPORT_FUNCTIONS: export SHELL_PLATFORM and shell_is_* functions for use 14 | # in other scripts. 15 | 16 | EXPORT_FUNCTIONS=true 17 | 18 | # Code 19 | # ---- 20 | 21 | # Avoid recursive invocation 22 | 23 | [ -n "$BASHRC_DISPATCH_PID" ] && [ $$ -eq "$BASHRC_DISPATCH_PID" ] && return 24 | BASHRC_DISPATCH_PID=$$ 25 | 26 | 27 | # Setup the main shell variables and functions 28 | 29 | if [ -z "$SHELL_PLATFORM" ]; then 30 | SHELL_PLATFORM='OTHER' 31 | case "$OSTYPE" in 32 | *'linux'* ) SHELL_PLATFORM='LINUX' ;; 33 | *'darwin'* ) SHELL_PLATFORM='OSX' ;; 34 | *'freebsd'* ) SHELL_PLATFORM='BSD' ;; 35 | *'cygwin'* ) SHELL_PLATFORM='CYGWIN' ;; 36 | esac 37 | fi 38 | 39 | if ! type -p shell_is_login ; then 40 | shell_is_linux () { [[ "$OSTYPE" == *'linux'* ]] ; } 41 | shell_is_osx () { [[ "$OSTYPE" == *'darwin'* ]] ; } 42 | shell_is_cygwin () { [[ "$OSTYPE" == *'cygwin'* ]] ; } 43 | shell_is_login () { shopt -q login_shell ; } 44 | shell_is_interactive () { test -n "$PS1" ; } 45 | shell_is_script () { ! shell_is_interactive ; } 46 | fi 47 | 48 | 49 | # Make $BASH_ENV the same in interactive and non-interactive scripts 50 | 51 | [ -z "$BASH_ENV" ] && export BASH_ENV="$BASH_SOURCE" 52 | 53 | 54 | # Make these available to the potentially convoluted bashrc_* startup scripts 55 | 56 | if $EXPORT_FUNCTIONS ; then 57 | export SHELL_PLATFORM 58 | export -f shell_is_linux 59 | export -f shell_is_osx 60 | export -f shell_is_cygwin 61 | export -f shell_is_login 62 | export -f shell_is_interactive 63 | export -f shell_is_script 64 | fi 65 | 66 | # Now dispatch special files 67 | PRF="${HOME}/." 68 | 69 | [ -f "${PRF}bashrc_once" ] && [ -z "$BRCD_RANONCE" ] && . "${PRF}bashrc_once" && export BRCD_RANONCE=true 70 | [ -f "${PRF}bashrc_all" ] && . "${PRF}bashrc_all" 71 | [ -f "${PRF}bashrc_script" ] && shell_is_script && . "${PRF}bashrc_script" 72 | [ -f "${PRF}bashrc_interactive" ] && shell_is_interactive && . "${PRF}bashrc_interactive" 73 | [ -f "${PRF}bashrc_login" ] && shell_is_login && . "${PRF}bashrc_login" 74 | 75 | 76 | # Unset variables if necessary to avoid env polution 77 | 78 | if ! $EXPORT_FUNCTIONS ; then 79 | unset SHELL_PLATFORM 80 | unset -f shell_is_linux 81 | unset -f shell_is_osx 82 | unset -f shell_is_cygwin 83 | unset -f shell_is_login 84 | unset -f shell_is_interactive 85 | unset -f shell_is_script 86 | fi 87 | 88 | 89 | # Unset local variables 90 | 91 | unset fn_cmd 92 | unset EXPORT_FUNCTIONS 93 | unset BASHRC_DISPATCH_PID 94 | unset PRF 95 | --------------------------------------------------------------------------------