Find an executable on the PATH
Before spawning a tool like git or ffmpeg, it is useful to know whether it is installed and where. This example implements the which command: scan each directory on the PATH for an executable file.
async function which(command: string): Promise<string | null> {
const PATH = Deno.env.get("PATH") ?? "";Windows separates entries with ";" and resolves extensions from PATHEXT; this example covers the common case.
const separator = Deno.build.os === "windows" ? ";" : ":";
for (const dir of PATH.split(separator)) {
if (dir === "") continue;
const candidate = `${dir}/${command}`;
try {
const info = await Deno.stat(candidate);On unix, check that some execute bit is set. Windows has no mode, so existence is the best cheap signal.
const executable = Deno.build.os === "windows" ||
((info.mode ?? 0) & 0o111) !== 0;
if (info.isFile && executable) {
return candidate;
}
} catch {Not in this directory; keep looking.
}
}
return null;
}
console.log(await which("git")); // /usr/bin/git
console.log(await which("definitely-not-installed")); // nullA typical use is a friendly error before spawning a subprocess.
const ffmpeg = await which("ffmpeg");
if (!ffmpeg) {
console.log("ffmpeg is required: https://ffmpeg.org/download.html");
}Reading the PATH requires -E, and stat-ing the candidates requires -R.
Run this example locally using the Deno CLI:
deno run -R -E https://docs.deno.com/examples/scripts/find_executable.ts