1

I've encountered a machine that does not have which. How would you find the path to an executable foo without which in a POSIX compliant shell script, if foo might not even be present?

The code I have does the following:

  • if which appears available according to type which exiting 0, then use it
  • otherwise use type foo and depending on what type says it is (does the output contain any of the following: keyword, builtin, alias, hash, function), grab the path according to its likely position in the output.

The main problem with this, as @chepner and the man page point out, is type stdout is in an unspecified format.

My other problem is foo might not ever exit, so I can't just execute it to see what happens. I want to inspect it first so I need to know where it is.

I feel find / -type f -name foo 2>/dev/null would take too long. I suppose I could iterate over $PATH to find it directly. Which approach is best? Iterating over $PATH or the approach in the two bullets above, or some other approach? I need the solution to be portable.

user1011471
  • 1,090
  • 2
  • 14
  • 34
  • 1
    `type -P` *only* does a path search; if you don't a binary named `type` in your path, it will exit with status 1. – chepner Sep 07 '16 at 17:35
  • How come you made this a comment instead of an answer? – user1011471 Sep 07 '16 at 18:44
  • I'm not sure it's a *good* answer. `type -P` isn't standard, so there is no guarantee that even if `type -P` is supported, it does what you are expecting it to do. – chepner Sep 07 '16 at 19:10
  • Ah, you're right (of course). "The standard output of type contains information about each operand in an unspecified format." Maybe I should change the question then. – user1011471 Sep 08 '16 at 16:36
  • `type stdout is in an unspecified format` While it is in unspecified format, there is only a limited count of existing shells that you are going to use - zsh, ash, dash, bash - and on all of them "it works" as in outputs just executable path. I once also [compiled&tested](https://stackoverflow.com/questions/14447555/posix-compliant-way-to-see-if-a-function-is-defined-in-an-sh-script/69037385#69037385) original ksh from SVR4, and type there also outputted the executable path. – KamilCuk Nov 15 '21 at 09:53

1 Answers1

1
command -v foo

will print the absolute path to foo, if it exists.

command [-p][-v|-V] command_name

-v Write a string to standard output that indicates the pathname or command that will be used by the shell, in the current shell execution environment [..], to invoke command_name, but do not invoke command_name.

Read more in the POSIX spec (functions, aliases, not found).