How do I test to see if an application exists in $PATH?

I’m trying to write all of my sh startup/env scripts to work with as much DRY and as much: “works on every *nix I clone it to”, as possible. This means making sure that if I try to run code that’s not there, that the code fails gracefully. To that end I need to be able to test if programs exist. I know how to test if a file exists, but I’m not sure how to test to see if an application is executable within the path. I’d rather use the $PATH, as some of these need to work on arch, ubuntu, and centos. Some might be installed in my homedir, on systems where I don’t have root, others might not be installed, and others yet my be installed in system paths.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Use type commandname. This returns true if commandname is anything executable: alias, function, built-in or external command (looked up in $PATH). Alternatively, use command commandname which returns true if commandname is a built-in or external command (looked up in $PATH).

exists () {
  type "$1" >/dev/null 2>/dev/null
}

There are a few sh variants (definitely pre-POSIX; I know of /bin/sh under OSF1 ≤3.x and some versions of the Almquist shell found in early NetBSD versions and a few 20th-century Linux distributions) where type always returns 0 or doesn’t exist. I don’t think any systems shipped with these this millennium. If you ever encounter them, here’s a function you can use to search in $PATH manually:
exists () { (
    IFS=:
    for d in $PATH; do
      if test -x "$d/$1"; then return 0; fi
    done
    return 1
) }

This function is generally useful if you want to exclude built-ins and functions and look up the name in $PATH. Most shells have a built-in for this, command -v, though it’s a relatively recent addition to POSIX (still optional as of POSIX:2004). It’s basically a programmer-friendly version of type: it prints the full path for an executable in $PATH, the bare name for a built-in or function, and an alias definition for an alias.
exists_in_path () {
  case $(command -v -- "$1") in
    /*) return 0;;
    alias *) return 1;; # alias
    *) return 1;; # built-in or function
  esac
}

Ksh, bash and zsh also have type -p to look up only executables in $PATH. Note that in bash, the return status of type -p foo is 0 if foo is a built-in or function; if you want to test for an executable in $PATH, you need to check that the output is not empty. type -p is not in POSIX; for instance Debian’s ash (which is /bin/sh on Ubuntu) doesn’t have it.

Method 2

If you are only looking for external programs, you can also use which. Don’t know how portable that is though.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments