diff options
-rwxr-xr-x | pathenv | 55 |
1 files changed, 55 insertions, 0 deletions
@@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [[ $# -eq 0 || $1 = "-h" || $1 = "--help" ]]; then + cat >&2 <<EOF +Usage: $0 [name=/path/to/executable]... -- <command...> + +Creates a temporary directory containing symlinks for each of the assignments +specified on the command line. This directory is prepended to \$PATH when +exectuing <command...>, with the effect that when the command looks up 'name' +in \$PATH, it will find /path/to/executable instead of whatever it currently +refers to in \$PATH. +EOF + if [[ $# -eq 0 ]]; then exit 1; fi + exit +fi + +tmpdir=$(mktemp -d) +trap 'rm -rf "$tmpdir"' EXIT + +found_dashes=0 +while [[ $# -gt 0 ]]; do + if [[ $1 = "--" ]]; then + shift + found_dashes=1 + break + fi + + name="${1%%=*}" # remove longest matching suffix + path="${1#*=}" # remove shortest matching prefix + if [[ ${#name} -eq 0 || ${#path} -eq 0 || ${#name} -ge ${#1} ]]; then + # {#name} == {#1} if there was no '=' in the argument to begin with + echo >&2 "pathenv: No '=' in argument or no name or path given: '$1'" + exit 1 + elif [[ -n ${name//[^\/]} ]]; then + echo >&2 "pathenv: '/' not allowed in name: '$1'" + exit 1 + else + ln -s "$(realpath "$path")" "$tmpdir/$name" + shift + fi +done + +if [[ $found_dashes -eq 0 ]]; then + echo >&2 "pathenv: '--' separating assignments and command is mandatory" + exit 1 +fi + +if [[ $# -eq 0 ]]; then + echo >&2 "pathenv: No command given" + exit 1 +fi + +# don't exec so that we can still cleanup tmpdir afterwards +PATH="$tmpdir:$PATH" "$@" |