Skip to content

Instantly share code, notes, and snippets.

@wd5gnr
Created March 5, 2025 21:15
Show Gist options
  • Save wd5gnr/c5681f2f7072938d5d7afe7a1e3e9132 to your computer and use it in GitHub Desktop.
Save wd5gnr/c5681f2f7072938d5d7afe7a1e3e9132 to your computer and use it in GitHub Desktop.
Project CD (example of making a dual-mode script that can alter the caller's environment)
PROJ_DIRS["docs"]="~/library/documents"
PROJ_DIRS["video"]="~/library/videos"
PROJ_DIRS["arduino"]="/home/alw/projects/embedded/Arduino"
#!/bin/bash
# This is not a bash shell script
# But needs to be sourced. However...
# Try:
# eval $(__project_dir.sh --__install project_dir)
if [[ "${BASH_SOURCE[0]}" == "$0" ]]
then
if [ "$1" == "--__install" ] # this should only be called from "real" script
then
aname="$2"
if [ "$aname" == "" ]
then
aname="pcd" # default alias name
fi
echo -n "alias '$aname'='source "
aname=$(realpath -s "$0")
echo "$aname'"
exit 0
fi
echo "You must source this script"
exit 1
fi
# Ok your script goes here
# If you call it from your alias
# you can change directories
# set environment variables, etc
# But don't exit! (use return)
# This version uses functions to control variable polution
# this is a simple example
# It maintains an array of project IDs and directories in the CONFIG file
# so for example...
# PROJ_DIRS["docs"]="~/library/documents"
# PROJ_DIRS["video"]="~/library/videos"
# etc...
#
# Then you can switch to a project by tag
# In addition, if the file ./.dir_exit is there
# it will be sourced before you leave and can
# potentially redirect things by setting
# PROJ_TMP, DIR_NEW and it can examine DIR_OLD
# If the new directory has ./.dir_enter it will also
# be sourced so it can examine the same variables
# You could also set other variables, aliases, etc on entry/exit
#
# Commands:
# eval $(_project_dir.sh --install pcd) # make alias pcd
# pcd {project} # change to project directory
# pcd --list # show all projects
# pcd --add {project} {dir} # add a project/directory
# (note: last one in the file wins, but old ones are still kept)
# pcd --edit # edit the config file using $EDITOR
main() {
local CONFIG=~/.proj_dirs
if [ "$1" == "--edit" ] # edit config file
then
$EDITOR "$CONFIG"
return 0
fi
if [ "$1" == "--add" ] # add a new entry to config
then
if [ -z "$2" ] || [ -z "$3" ]
then
echo Usage --add project dir
return 1
fi
echo "Adding $2"
echo PROJ_DIRS[\""$2"\"]=\""$3"\" >>"$CONFIG"
return 0
fi
# load project directories
declare -A PROJ_DIRS # note that declare makes local variables
source "$CONFIG"
if [ "$1" == "--list" ] # show directories
then
local key
for key in "${!PROJ_DIRS[@]}"
do
echo "$key: ${PROJ_DIRS[$key]}"
done
return 0
fi
# clear out --help or -h so we get default help message
# instead of trying to set project --help
if [ "$1" == "--help" ] || [ "$1" == "-h" ]
then
set --
fi
local PROJ_TEMP DIR_NEW
# make sure project exists
if [ "$1" != "" ]
then
if [ "${PROJ_DIRS[$1]}" == "" ]
then
echo "Warning Unknown project $1"
PROJ_TEMP=-
DIR_NEW="$1"
else
PROJ_TEMP="$1"
DIR_NEW="${PROJ_DIRS[$1]}"
fi
fi
# do the switch
if [ "$1" != "" ]
then
local DIR_OLD=$(pwd) # just in case one of the scripts wants it
if [ -r ./.dir_exit ] # note this could set PROJ_TMP or DIR_NEW
then
source ./.dir_exit
fi
echo "Setting project $PROJ_TMP"
cd "$DIR_NEW" || echo change directory failed
if [ -r ./.dir_enter ]
then
source ./.dir_enter
fi
return 0
fi
# help
if [ "$1" == "" ]
then
'cat' << EOF
A project management script (Al Williams/Hackaday)
You first register it using:
eval \$(__project_dir.sh --install pcd) # make alias pcd (or whatever you want)
Commands:
pcd {project} # change to project directory
pcd --list # show all projects
pcd --add {project} {dir} # add a project/directory
(note: last one in the file wins, but old ones are still kept)
pcd --edit # edit the config file using $EDITOR
EOF
return 0
fi
}
# Be sure to have this at the end
__go__() {
local tmprv
main "$@"
tmprv=$?
unset main, __go__
return $tmprv
}
__go__ "$@"
return $?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment