Skip to content

Instantly share code, notes, and snippets.

@RoUS
Created January 7, 2016 17:25
Show Gist options
  • Save RoUS/5d30a22e4f526ab1f751 to your computer and use it in GitHub Desktop.
Save RoUS/5d30a22e4f526ab1f751 to your computer and use it in GitHub Desktop.
Bash functions for doing things on cd into/out of directories
#
# This function provides for sourcing of shell scripts when moving
# into (or out of) a directory.
#
# If the command exits with a non-zero status, or the working
# directory isn't changed, no scripts are processed.
#
# If the command exits with a 0 status and the current working
# directory does change, the previous directory is checked for an
# ".on_exit" file. If found, it gets sourced. Similarly, the new WD
# is checked for a readable ".on_entry" file, which gets sourced if
# found.
#
# The return status depends on the exit status of the command and the
# sourced scripts. If the command returns non-zero, the scripts do
# not get sourced, and the command's exit status is returned. If the
# .on_entry script is sourced and returns non-zero, that will be the
# function's return value. If both the command and any .on_entry
# script return zero, but any sourced .on_exit script exits with a
# non-zero status, *that* will be the function's return value.
#
# Usage:
# _chdir BUILTIN-COMMAND [command-args]
#
function _chdir() {
local _cmd=$1
shift
local _pwd="${PWD}"
local _on_exit="${_pwd}/.on_exit"
builtin "${_cmd}" $*
local _cmdstat=$?
local _exit_stat=0
local _entry_stat=0
if [[ $_cmdstat == 0 ]] && [ "${PWD}" != "${_pwd}" ]; then
local _on_entry="${PWD}/.on_entry"
if [ -r "${_on_exit}" ]; then
. "${_on_exit}"
_exit_stat=$?
[[ $_exit_stat != 0 ]] && _cmd_stat=$_exit_stat
fi
if [ -r "${_on_entry}" ]; then
. "${_on_entry}"
_entry_stat=$?
[[ $_entry_stat != 0 ]] && _cmd_stat=$_entry_stat
fi
fi
return ${_cmdstat}
}
export -f _chdir
#
# Define similar functions for any/all built-in commands that change
# the working directory.
#
function cd() {
_chdir cd $*
}
export -f cd
function pushd() {
_chdir pushd $*
}
export -f pushd
function popd() {
_chdir popd $*
}
export -f popd
#
# Try to find the non-symlinked path to either our caller or to
# whatever argument was passed.
#
# If which(1) can find the target, we use that location instead.
#
# If the target doesn't exist, print an empty string.
#
# Useful in scripts that want to find out where they are.
#
function where-am-i() {
local _target="${1:-${BASH_SOURCE[1]}}"
local _executable="$(which "${_target}" 2> /dev/null)"
local _path=''
[ -n "${_executable}" ] && _target="${_executable}"
if [ ! -e "${_target}" ] ; then
return 1
fi
_path="$(builtin cd "$(dirname "${_target}")" ; pwd -P)"
echo "${_path}"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment