bashpathposix

How to find a file on the $PATH in Bash?


The utility which will find a program on the path but what about an arbitrary data file?

I must be searching for the wrong stuff but I can't find any way to do this with a standard utility so I thought of writing a little Bash script to do it.

The $PATH environment variable is separated by colons, but trying to set IFS=':' and then iterate over the results is not working for me. Here's what I've got so far:

IFS=':' DIRS=($PATH)
for d in $DIRS; do echo $d; done

At this point it only outputs the first entry in my path rather than all of them.

Thoughts? If there's already a standard command that does this then there's no reason to write a script ...


Solution

  • A few of things going on here:

    1. IFS=':' DIRS=($PATH)

      bash will expand the variable before setting IFS and DIRS, so it's too late by then. You'll need something crazy like

      dirs=()
      while IFS= read -r -d: dir || [ "$dir" ]; do dirs+=("$dir"); done <<<"$PATH"
      

    -- nope, that was wrong. First the $PATH variable is expanded, then IFS is set, then the DIRS element is split using IFS because it is unquoted.

    1. for d in $DIRS; do echo $d; done

      To iterate over all the elements of an array, you need

      for d in "${dirs[@]}" ...
      

      With an array, $DIRS is equal to ${DIRS[0]}, i.e. the first entry.

    2. Don't use ALLCAPS varnames. It's too easy to overwrite a crucial system variable.

    3. Quote your variables unless you know exactly what will happen if you don't.