Skip to content

Instantly share code, notes, and snippets.

@CRThaze
Last active August 9, 2024 14:43
Show Gist options
  • Save CRThaze/1137d0cf2572d078292565685b722a9c to your computer and use it in GitHub Desktop.
Save CRThaze/1137d0cf2572d078292565685b722a9c to your computer and use it in GitHub Desktop.
`which` is frankly insufficient. Whence fully resolves symlinks, and tells you if a command is something else like a function or built-in.
function whence() {
local print_links=false
local command=""
local batch=false
# Manual option parsing
for arg in "$@"; do
case "$arg" in
-p)
print_links=true
;;
-h)
tabs 2
echo "Usage:"
echo -e "\twhence [-q] [-p | -h] <command>"
echo -e "\t\t-h: Print Usage"
echo -e "\t\t-p: Print each symlink path"
echo -e "\t\t-b: Batch mode, only print paths"
tabs
return
;;
-b)
batch=true
;;
-*)
echo "Invalid option: $arg" >&2
return
;;
*)
command="$arg"
;;
esac
done
# Ensure a command was provided
if [[ -z "$command" ]]; then
echo "No command provided" >&2
return
fi
# Find the initial path using which
local original_path=$(which "$command" 2> /dev/null)
local path=$original_path
if [[ -z "$path" ]]; then
if (type -t "$command" >/dev/null)
then
type=$(type -t "$command")
echo "$command is a $type"
if [[ "$type" == "function" ]]
then
echo "Run: \`type $command\` to see its definition."
fi
return
else
echo "$command not found"
return
fi
fi
# Follow symlinks
while [[ -L "$path" ]]; do
if [[ "$print_links" == "true" ]]
then
if [[ "$batch" == "false" ]]
then
echo -ne "Link:\t\t"
fi
echo "$path -> $(readlink -f "$path")"
fi
path=$(readlink -f "$path")
done
if [[ "$batch" == "false" ]]
then
if [[ "$path" == "$original_path" ]]
then
echo -ne "Executable:\t"
else
echo -ne "Ultimate Exe:\t"
fi
fi
echo "$path"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment