Sample Header Ad - 728x90

Does any implementation of `which` output "no" when executable cannot be found?

4 votes
2 answers
1020 views
I am reading the [source code of the Maven wrapper written for the Bourne shell](https://github.com/apache/maven-wrapper/blob/102d7b50cd756b0ac922ef07378c1fe3c9686473/maven-wrapper-distribution/src/resources/mvnw#L103) . I came across these lines:
if [ -z "$JAVA_HOME" ]; then
    javaExecutable="$(which javac)"
    if [ -n "$javaExecutable" ] && ! [ "$(expr "$javaExecutable" : '\([^ ]*\)')" = "no" ]; then
# snip
expr when used with arg1 and arg2 and a : matches arg1 against the regex arg2. Normally, the result would be the amount of matching characters, e.g.:
$ expr foobar : foo
3
However, when using capturing parentheses (\( and \)), it returns the content of the first capturing parentheses:
$ expr foobar : '\(foo\)'
foo
So far, so good. If I evaluate the expression from the source quoted above on my machine, I get:
$ javaExecutable=$(which javac)
$ expr "$javaExecutable" : '\([^ ]*\)'
/usr/bin/javac
For a non-existing executable:
$ nonExistingExecutable=$(which sjdkfjkdsjfs)
$ expr "$nonExistingExecutable" : '\([^ ]*\)'
Which means that for a non-existing executable the output is a empty string with newline. What's puzzling me in the source is how the output of which javac (arg1 to expr) ever returns the string no? Is there some version of which which, instead of returning nothing, returns no when no executable can be found? If not, this statement always evaluates to true and that would be weird.
Asked by Stefan van den Akker (352 rep)
Feb 14, 2024, 11:50 AM
Last activity: Feb 16, 2024, 02:42 PM