mirror of
https://github.com/pyenv/pyenv.git
synced 2024-11-21 20:47:00 -05:00
0324b118ee
A trap on the special signal EXIT is executed before the shell terminates. EXIT actually covers SIGINT and SIGTERM as well, and we don't need any extra traps for them. See bash(1) and "help trap" in bash.
75 lines
2 KiB
Bash
Executable file
75 lines
2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
set -e
|
|
[ -n "$RBENV_DEBUG" ] && set -x
|
|
|
|
SHIM_PATH="${RBENV_ROOT}/shims"
|
|
PROTOTYPE_SHIM_PATH="${SHIM_PATH}/.rbenv-shim"
|
|
|
|
# Create the shims directory if it doesn't already exist.
|
|
mkdir -p "$SHIM_PATH"
|
|
|
|
# Ensure only one instance of rbenv-rehash is running at a time by
|
|
# setting the shell's `noclobber` option and attempting to write to
|
|
# the prototype shim file. If the file already exists, print a warning
|
|
# to stderr and exit with a non-zero status.
|
|
set -o noclobber
|
|
{ echo > "$PROTOTYPE_SHIM_PATH"
|
|
} 2>/dev/null ||
|
|
{ echo "rbenv: cannot rehash: $PROTOTYPE_SHIM_PATH exists"
|
|
exit 1
|
|
} >&2
|
|
set +o noclobber
|
|
|
|
# If we were able to obtain a lock, register a trap to clean up the
|
|
# prototype shim when the process exits.
|
|
trap remove_prototype_shim EXIT
|
|
|
|
remove_prototype_shim() {
|
|
rm -f "$PROTOTYPE_SHIM_PATH"
|
|
}
|
|
|
|
# The prototype shim file is a script that re-execs itself, passing
|
|
# its filename and any arguments to `rbenv exec`. This file is
|
|
# hard-linked for every binary and then removed. The linking technique
|
|
# is fast, uses less disk space than unique files, and also serves as
|
|
# a locking mechanism.
|
|
create_prototype_shim() {
|
|
cat > "$PROTOTYPE_SHIM_PATH" <<SH
|
|
#!/usr/bin/env bash
|
|
set -e
|
|
export RBENV_ROOT="$RBENV_ROOT"
|
|
exec rbenv exec "\${0##*/}" "\$@"
|
|
SH
|
|
chmod +x "$PROTOTYPE_SHIM_PATH"
|
|
}
|
|
|
|
# Make shims by iterating over every filename argument and creating a
|
|
# hard link from the prototype shim to a file of the same name in the
|
|
# shims directory, if one does not already exist.
|
|
make_shims() {
|
|
local glob="$@"
|
|
|
|
for file in $glob; do
|
|
local shim="${file##*/}"
|
|
[ -e "$shim" ] || ln -f "$PROTOTYPE_SHIM_PATH" "$shim"
|
|
done
|
|
}
|
|
|
|
# Save the working directory.
|
|
CUR_PATH=$PWD
|
|
|
|
# Empty out the shims directory and make it the working directory.
|
|
rm -f "$SHIM_PATH"/*
|
|
cd "$SHIM_PATH"
|
|
|
|
# Create the prototype shim, then make shims for all known binaries.
|
|
create_prototype_shim
|
|
shopt -s nullglob
|
|
make_shims ../versions/*/bin/*
|
|
|
|
# Restore the previous working directory.
|
|
cd "$CUR_PATH"
|
|
|
|
for script in $(rbenv-hooks rehash); do
|
|
source "$script"
|
|
done
|