Skip to content

Commit 32d7a24

Browse files
authored
fix: use "command -v" to find interpreter in $PATH (#3150)
In some environments, `which` doesn't work correctly under Bazel, while `command -v` does. I think the difference is that `command` is a shell builtin (and POSIX compliant), whereas `which` is not: ``` $ sh -c 'builtin command -v python3' /usr/bin/python3 $ sh -c 'builtin which python3' sh: line 1: builtin: which: not a shell builtin ``` While `command -v` performs fewer checks under the hood, it is more portable.
1 parent e3655c2 commit 32d7a24

File tree

2 files changed

+7
-7
lines changed

2 files changed

+7
-7
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ END_UNRELEASED_TEMPLATE
101101
`# gazelle:python_resolve_sibling_imports true`
102102
* (pypi) Show overridden index URL of packages when downloading metadata have failed.
103103
([#2985](https://github.com/bazel-contrib/rules_python/issues/2985)).
104+
* (toolchains) use "command -v" to find interpreter in `$PATH`
105+
([#3150](https://github.com/bazel-contrib/rules_python/pull/3150)).
104106

105107
{#v0-0-0-added}
106108
### Added

python/private/runtime_env_toolchain_interpreter.sh

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,14 @@ die() {
1717
exit 1
1818
}
1919

20-
# We use `which` to locate the Python interpreter command on PATH. `command -v`
21-
# is another option, but it doesn't check whether the file it finds has the
22-
# executable bit.
20+
# We use `command -v` to locate the Python interpreter command on PATH.
2321
#
2422
# A tricky situation happens when this wrapper is invoked as part of running a
2523
# tool, e.g. passing a py_binary target to `ctx.actions.run()`. Bazel will unset
2624
# the PATH variable. Then the shell will see there's no PATH and initialize its
27-
# own, sometimes without exporting it. This causes `which` to fail and this
25+
# own, sometimes without exporting it. This causes `command -v` to fail and this
2826
# script to think there's no Python interpreter installed. To avoid this we
29-
# explicitly pass PATH to each `which` invocation. We can't just export PATH
27+
# explicitly pass PATH to each `command -v` invocation. We can't just export PATH
3028
# because that would modify the environment seen by the final user Python
3129
# program.
3230
#
@@ -37,9 +35,9 @@ die() {
3735
# https://github.com/bazelbuild/bazel/issues/8415
3836

3937
# Try the "python3" command name first, then fall back on "python".
40-
PYTHON_BIN="$(PATH="$PATH" which python3 2> /dev/null)"
38+
PYTHON_BIN="$(PATH="$PATH" command -v python3 2> /dev/null)"
4139
if [ -z "${PYTHON_BIN:-}" ]; then
42-
PYTHON_BIN="$(PATH="$PATH" which python 2>/dev/null)"
40+
PYTHON_BIN="$(PATH="$PATH" command -v python 2>/dev/null)"
4341
fi
4442
if [ -z "${PYTHON_BIN:-}" ]; then
4543
die "Neither 'python3' nor 'python' were found on the target \

0 commit comments

Comments
 (0)