Created
March 5, 2025 21:15
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PROJ_DIRS["docs"]="~/library/documents" | |
PROJ_DIRS["video"]="~/library/videos" | |
PROJ_DIRS["arduino"]="/home/alw/projects/embedded/Arduino" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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