Skip to content

Instantly share code, notes, and snippets.

@kimsondrup
Last active May 17, 2024 08:43
Show Gist options
  • Save kimsondrup/a3003b0038a6f6ea69b0d27033bb0712 to your computer and use it in GitHub Desktop.
Save kimsondrup/a3003b0038a6f6ea69b0d27033bb0712 to your computer and use it in GitHub Desktop.
WSL wrapper: Filter Windows path from the PATH env. for "linked" commands
#!/usr/bin/env bash
# This script is designed to introduce "filtered PATH" where Windows paths (/mnt/<drive letter>) are removed
# as to help with commands that have problems handling those paths being present in PATH.
# To use this script you need to create a symlink pointing to this script with the same name as a command in your PATH,
# this script will find and execute the original command from the filtered PATH and passing on the filtered PATH.
# Note that you need to create the symlink manually before using this script.
# The symlink could be placed in a directory located at "$HOME/bin" in PATH and creating the link there
# See https://gist.github.com/kimsondrup/f22717fa7677b21d14284964fc8d06e7
# (yes, I am shamelessly promoting my own few lines of code for this simple task)
# I original made this to fix problems I had with kubectl (see https://github.com/kubernetes/kubectl/issues/1336)
# and also to have some fun.
# Another way to solve this could be to set "appendWindowsPath = false" in /etc/wsl.conf
# but this will affect the entire WSL distro
# set -x # Debug
set -e
set -o pipefail
set -o nounset
set -o noclobber
# Strip WSL Windows path from PATH environment variable
strip_windows_paths() {
local path="$1"
local new_path=""
local p=""
local path_arr=()
IFS=: read -ra path_arr <<< "$path"
for p in "${path_arr[@]}"; do
if ! [[ "$p" =~ ^/mnt/[a-z]/ ]]; then
new_path="${new_path}${p}:"
fi
done
echo "${new_path%:}"
}
# Filter PATH environment variable to remove WSL Windows paths
PATH="$(strip_windows_paths "$PATH")"
export PATH
resolved_source_path="$(readlink -f "${BASH_SOURCE[0]}")"
target_command="$(basename "${BASH_SOURCE[0]}")"
# Find all paths for the command in the filtered PATH
read -ra command_paths -d '' < <(which -a "$target_command" || true) || true
# If no command paths were found, exit with an error
if [[ -z "${command_paths[*]}" ]]; then
>&2 printf 'Command "%s" not found in filtered PATH\n' "$target_command"
exit 1
fi
# Loop through each command path found and execute the first one that is not the current script
for command_path in "${command_paths[@]}"; do
resolved_path=$(readlink -f "$command_path")
if [ "$resolved_path" != "$resolved_source_path" ]; then
exec "$command_path" "$@"
fi
done
# If no valid command paths were found, exit with an error
>&2 printf 'Command "%s" not found in filtered PATH\n' "$target_command"
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment