diff options
| author | Tom Smeding <tom@tomsmeding.com> | 2025-01-17 13:17:58 +0100 | 
|---|---|---|
| committer | Tom Smeding <tom@tomsmeding.com> | 2025-01-17 13:17:58 +0100 | 
| commit | dd86ad8e4c8a76a24c693ff23ac91ac250fa4ccf (patch) | |
| tree | 36f93fa8abc41ddf2c1871a2d407876b369f45e4 | |
Initial
| -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" "$@" | 
