Skip to content

Instantly share code, notes, and snippets.

@asdf913
Last active May 7, 2026 10:15
Show Gist options
  • Select an option

  • Save asdf913/8cebfe7b8fb2c83ecd2aad1bfc1a99d2 to your computer and use it in GitHub Desktop.

Select an option

Save asdf913/8cebfe7b8fb2c83ecd2aad1bfc1a99d2 to your computer and use it in GitHub Desktop.
Use "which" or "where" to determine if a command is valid. Also print the path of the corresponding executable of the command. Print the actual path if the path is a link
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.22.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.20.0</version>
</dependency>
</dependencies>
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.util.Objects;
import java.util.function.Predicate;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.function.FailableFunction;
public class WhichOrWhere {
public static void main(String[] args) throws IOException {
//
System.out.println(getName(getClass(FileSystems.getDefault())));
//
final String command = "java";
//
System.out.println(exists(command));
//
final File file = getFile(command);
//
System.out.println(file);
//
System.out.println(isLink(file));
//
System.out.println(getActualFile(command));
//
}
private static File getActualFile(final String command) throws IOException {
//
File file = getFile(command);
//
while (file != null && exists(file) && isLink(file)) {
//
if (!isLink(file = readlink(file))) {
//
break;
//
} // if
//
} // while
//
return file;
//
}
private static boolean isLink(final File file) throws IOException {
//
if (file == null) {
//
return false;
//
} // if
//
if (isLinux()) {
//
final File readlink = testAndApply(Objects::nonNull, file, WhichOrWhere::readlink, null);
//
return readlink != null
&& !Objects.equals(readlink.getAbsolutePath(), file != null ? file.getAbsolutePath() : null);
//
} // if
//
return false;
//
}
private static boolean isLinux() {
//
return Objects.equals(getName(getClass(FileSystems.getDefault())), "sun.nio.fs.LinuxFileSystem");
//
}
private static File readlink(final File file) throws IOException {
//
if (isLinux()) {
//
try (final InputStream is = getInputStream(
start(new ProcessBuilder("readlink", file != null ? file.getAbsolutePath() : null)))) {
//
return testAndApply(StringUtils::isNotEmpty,
StringUtils.trim(IOUtils.toString(is, StandardCharsets.UTF_8)), File::new, null);
//
} // try
//
} // if
//
return null;
//
}
private static File getFile(final String command) throws IOException {
//
String whichOrWhere = "which";
//
if (Objects.equals(getName(getClass(FileSystems.getDefault())), "sun.nio.fs.WindowsFileSystem")) {
//
whichOrWhere = "where";
//
} // if
//
try (final InputStream is = getInputStream(start(new ProcessBuilder(whichOrWhere, command)))) {
//
return testAndApply(Objects::nonNull, StringUtils.trim(IOUtils.toString(is, StandardCharsets.UTF_8)),
File::new, null);
//
} // try
//
}
private static String getName(final Class<?> instance) {
return instance != null ? instance.getName() : null;
}
private static Class<?> getClass(final Object instance) {
return instance != null ? instance.getClass() : null;
}
private static boolean exists(final String command) throws IOException {
//
return exists(getFile(command));
//
}
private static boolean exists(final File instance) {
return instance != null && instance.exists();
}
private static <T, R, E extends Throwable> R testAndApply(final Predicate<T> predicate, final T value,
final FailableFunction<T, R, E> functionTrue, final FailableFunction<T, R, E> functionFalse) throws E {
return predicate != null && predicate.test(value) ? apply(functionTrue, value) : apply(functionFalse, value);
}
private static <T, R, E extends Throwable> R apply(final FailableFunction<T, R, E> instance, final T value)
throws E {
return instance != null ? instance.apply(value) : null;
}
private static InputStream getInputStream(final Process instance) {
return instance != null ? instance.getInputStream() : null;
}
private static Process start(final ProcessBuilder instance) throws IOException {
return instance != null ? instance.start() : null;
}
}
@asdf913
Copy link
Copy Markdown
Author

asdf913 commented May 7, 2026

Sample output

sun.nio.fs.LinuxFileSystem
true
/usr/bin/java
true
/usr/lib/jvm/jdk-25-oracle-x64/bin/java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment