Usage
- To create a localenv called sicp, do
$ localenv sicp
- Activate the localenv:
$ . sicp/bin/activate
- Check installed eggs in the local repository:
$ chicken-status
- Install a new egg called 'sicp' in the local repository:
$ chicken-install sicp
- Deactivate the localenv:
$ deactivate
This is the first time I have used bash for any purpose at all. Is there any other way to get the grandparent directory of the current directory?
#!/bin/bash
if [ -z "${1}" ]; then
echo 'Usage: localenv DIR'
echo
echo 'localenv: You must provide the name of the directory to install the chicken environment.'
exit 1
elif [ -e "$(pwd)/${1}" ]; then
echo 'localenv: file or directory already exists.'
exit 1
fi
# check if chicken is installed and save the location of csi and chicken-install.
CSI=$(command -v csi)
if [ -z "${CSI}" ]; then
echo 'CHICKEN is not installed!'
exit 1
else
echo "CHICKEN interpreter is at ${CSI}"
fi
CHICKEN_INSTALL=$(command -v chicken-install)
# obtain global CHICKEN_HOME, CHICKEN_PREFIX, CHICKEN_REPOSITORY paths
CHICKEN_HOME=$(${CSI} -p "(chicken-home)")
CHICKEN_PREFIX="$(dirname $(dirname ${CHICKEN_HOME}))"
CHICKEN_REPOSITORY=$(${CSI} -p "(repository-path)")
# chicken binary version
BINARY_VERSION=$(basename "${CHICKEN_REPOSITORY}")
# local copy of chicken files are kept here
LOCAL_CHICKEN_PREFIX=$(realpath "${1}")
# remember where we were before jumping directories
OLDPWD=$(pwd)
# create all the necessary directories
mkdir -p "${LOCAL_CHICKEN_PREFIX}" && cd "$_" || exit 1
mkdir -p bin lib/chicken share/chicken include/chicken
# populate ./bin
for file in ${CHICKEN_PREFIX}/bin/{chicken,chicken-bug,chicken-install,chicken-profile,chicken-status,chicken-uninstall,csi,csc,feathers}; do
[ -f "${file}" ] && cp "${file}" ./bin
done
# initialize empty alternative repository
${CHICKEN_INSTALL} -init "./lib/chicken/${BINARY_VERSION}"
# include files are essential
cp -R "${CHICKEN_PREFIX}"/include/chicken/{chicken.h,chicken-config.h} ./include/chicken
# populate ./share
cp -R "${CHICKEN_HOME}/setup.defaults" ./share/chicken
# create init file for the localenv
# init file acts like .csirc for the localenv
touch "${LOCAL_CHICKEN_PREFIX}/.init"
# write activate file
# Backslash escapes '$' and prevents expansion of the shell variables
cat << EOF > "${LOCAL_CHICKEN_PREFIX}/bin/activate"
export OLDPATH="\${PATH}"
export PATH="${LOCAL_CHICKEN_PREFIX}/bin:\${PATH}"
export OLDPS1="\${PS1}"
export PS1="(1ドル)\${PS1}"
export CHICKEN_PREFIX="${LOCAL_CHICKEN_PREFIX}"
export CHICKEN_HOME="${LOCAL_CHICKEN_PREFIX}/share/chicken"
export CHICKEN_REPOSITORY="${LOCAL_CHICKEN_PREFIX}/lib/chicken/${BINARY_VERSION}"
export LOCAL_CSIRC="${LOCAL_CHICKEN_PREFIX}/.init"
# register a feature identifier 'localenv'
# this is required to override commands in the .csirc file
alias csi="csi -D localenv"
# deactivation function
deactivate()
{
export PATH="\${OLDPATH}"
export PS1="\${OLDPS1}"
unset OLDPATH
unset OLDPS1
unset CHICKEN_PREFIX
unset CHICKEN_HOME
unset CHICKEN_REPOSITORY
unset LOCAL_CSIRC
unalias csi
unset -f deactivate
}
EOF
cd "${OLDPWD}"
1 Answer 1
I don't understand why the $(pwd)/
prefix is needed in this condition:
elif [ -e "$(pwd)/${1}" ]; then
If ${1}
is an absolute path, the condition may not match the directory, even if it exists. Why not write simply [ -e "${1}" ]
, which should work well with both relative and absolute paths.
OLDPWD
is automatically set by Bash when you change directories,
no need to set it manually.
In any case, since the script is intended to be executed instead of sourced,
there's no need to cd
back to $OLDPWD
.
As for $(dirname $(dirname ${CHICKEN_HOME}))
, I think that's nicely readable. For the record, you could use ${CHICKEN_HOME%/*}
twice to strip suffixes until the grandparent (+ an extra check for the special case of /
). Since parameter expansion is a built-in, this would be faster than executing dirname
twice. The performance would make a difference if you called dirname
a thousand times in a loop, but that's not the case here. And since using dirname
is simpler and more readable, I would stick with that.
"${CHICKEN_HOME}/../.."
, which is valid even if$CHICKEN_HOME
is root. I prefer your current "double dirname" though. \$\endgroup\$