From a33b30fa2db1211ccecd8e0079dd476692ce99d6 Mon Sep 17 00:00:00 2001 From: Tim Hawes Date: Sun, 2 Aug 2026 21:39:49 -0400 Subject: [PATCH 1/2] versions: fix --executables portability regression Replace the use of `xargs -r` and `basename -a` in the `--executables` fast path with Bash 3.2-compatible parameter expansion. The previous implementation relied on non-portable utility options, causing `pyenv rehash` and shell initialization to fail on illumos, OpenBSD, and other non-GNU userlands. Preserve the optimized executable discovery path by continuing to discover executables directly from the versions directory and deduplicate their basenames. --- libexec/pyenv-versions | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libexec/pyenv-versions b/libexec/pyenv-versions index 91cb56d4..1466209c 100755 --- a/libexec/pyenv-versions +++ b/libexec/pyenv-versions @@ -42,9 +42,15 @@ versions_dir="${PYENV_ROOT}/versions" if [[ -n "$executables" ]]; then if [ -d "$versions_dir" ]; then shopt -s dotglob nullglob - # MacOS 12+ and FreeBSD 15 support `xargs -r -0' and `basename -a' - # `sort -u` is simpler and a bit faster than `awk '!seen[$0]++'`, with the same result for rehash purposes - printf '%s\0' "$versions_dir"/*/bin/* "$versions_dir"/*/envs/*/bin/* | xargs -0 -r basename -a | sort -u + # Fast path for rehash: skip filtering and link resolution. + # Discover executables directly from the versions directory and + # deduplicate their basenames. Use bash 3.2 conventions to keep code portable. + for path in \ + "$versions_dir"/*/bin/* \ + "$versions_dir"/*/envs/*/bin/* + do + printf '%s\n' "${path##*/}" + done | sort -u shopt -u dotglob nullglob fi exit 0 From bb07d2e18a5d62a03a1053cd62d2ff9dc74026de Mon Sep 17 00:00:00 2001 From: Tim Hawes Date: Mon, 3 Aug 2026 20:55:42 -0400 Subject: [PATCH 2/2] versions: fix portability regression in --executables Commit 8037f226 introduced the `--executables` fast path using `xargs -r` and `basename -a`. Those options are unavailable on illumos and OpenBSD, breaking `pyenv rehash` on those platforms. Replace the GNU-specific invocation with a Bash 3.2-compatible implementation while preserving the direct executable discovery optimization. --- libexec/pyenv-versions | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/libexec/pyenv-versions b/libexec/pyenv-versions index 1466209c..1630503c 100755 --- a/libexec/pyenv-versions +++ b/libexec/pyenv-versions @@ -45,12 +45,10 @@ if [[ -n "$executables" ]]; then # Fast path for rehash: skip filtering and link resolution. # Discover executables directly from the versions directory and # deduplicate their basenames. Use bash 3.2 conventions to keep code portable. - for path in \ - "$versions_dir"/*/bin/* \ - "$versions_dir"/*/envs/*/bin/* - do - printf '%s\n' "${path##*/}" - done | sort -u + paths=( "$versions_dir"/*/bin/* "$versions_dir"/*/envs/*/bin/* ) + if [ "${#paths[@]}" -gt 0 ]; then + printf '%s\n' "${paths[@]##*/}" | sort -u + fi shopt -u dotglob nullglob fi exit 0