1+ #! /usr/bin/env bash
2+ #
3+ # Summary: Find virtual environments that use pyenv-managed versions.
4+ #
5+ # Usage: pyenv users [directory]
6+ #
7+ # Scans [directory] for virtual environments whose `python` commands
8+ # are symlinks back into a pyenv version. Default: current directory.
9+ #
10+ # I'm not a script writer so it's probably a bit crude, but I find it
11+ # helpful for checking if I can uninstall old Python versions. Uses
12+ # the `column` command from the util-linux package (if available) for
13+ # pretty-printing the output.
14+
15+ if [ -n " $1 " ]; then
16+ DIR=" $1 "
17+ else
18+ DIR=" $PYENV_DIR "
19+ fi
20+
21+ cmd=" readlink -f '{}' | grep -q ${PYENV_ROOT} "
22+ unset links i
23+ while IFS= read -r -d $' \0' file; do
24+ links[i++]=" $file "
25+ done < <( find " $DIR " -name " python" -type l -exec sh -c " $cmd " \; -print0)
26+
27+ # Exit if no venvs are using a pyenv-managed Python installation
28+ if [[ $i -eq 0 ]]; then
29+ exit 0
30+ fi
31+
32+ # Use columnar output if convenient.
33+ if [ -n " $( command -v column) " ]; then
34+ output=" column -t -s ':'"
35+ else
36+ output=" cat"
37+ fi
38+
39+ # Regex to extract the pyenv version from the target string. The
40+ # second group consumes the actual binary (`python`, `pypy3`, etc)
41+ regex=" ${PYENV_ROOT} /versions/(.+)/bin/(.+)"
42+
43+ for link in " ${links[@]} " ; do
44+ # `$link` is the `python` symlink, and `$target` is its target.
45+ target=$( readlink -f " $link " )
46+ # Ignore symlinks inside $PYENV_ROOT itself
47+ if echo " $link " | grep -v -q " $PYENV_ROOT " ; then
48+ [[ " $target " =~ $regex ]]
49+ version=" ${BASH_REMATCH[1]} "
50+ echo $version :${link% " /bin/python" }
51+ fi
52+ done | sort | $output
0 commit comments