# Portable method to find file along path



## Michael-Sanders (Feb 9, 2013)

Trying to find both a portable & posix method to test for the existence of a given file along the default system path using -only- builtins(1), if you have a more succinct method, I'd like to study your snippet. The following works, but somehow feels like I'm on the wrong track...


```
#!/bin/sh

got_tool() {
    builtin command -v $1 > \
    /dev/null && return 0 || return 1;
}

got_tool cat
echo $?

got_tool maybe_not_on_users_system
echo $?
```

To clarify... Can't use 'test -e fubar' or '[ -e fubar ]' because these require a path, I simply want to confirm the file is along the users path somewhere.


----------



## wblock@ (Feb 9, 2013)

There is which(1).  In csh(1), it reports builtins, but not in sh(1):

```
% echo $SHELL
/bin/csh
% which cd
cd: shell built-in command.
% sh
$ which cd
/usr/bin/cd
```


----------



## Michael-Sanders (Feb 9, 2013)

Sure enough... script in question assumes /bin/sh so I can't use which. I'm stumped for the time being :/


----------



## wblock@ (Feb 9, 2013)

But since you know that it will not be built in, always use the standalone command.


```
CD=`which cd`

if [ -n "$CD" ]; then
  echo "using $CD"
else
  echo "how did you get a system with no cd?"
fi
```


----------



## gordon@ (Feb 9, 2013)

```
#! /bin/sh

got_tool() {
        local IFS=:

        for dir in $PATH; do
                if [ -x "$dir/$1" ]; then
                        return 0
                fi
        done

        return 1
}

got_tool cat
echo $?

got_tool notatool
echo $?
```


----------



## fonz (Feb 9, 2013)

I don't know whether it helps at all, but sh(1) also has the built-in command builtin which, when called with a command as argument, returns 0 it it's built-in and non-zero (plus a diagnostic message I can't seem to easily filter out with conventional redirection to /dev/null) if it's not. Example: `% builtin [i]foo[/i] && echo "built-in" || echo "not built-in"`


----------



## Michael-Sanders (Feb 10, 2013)

wblock@ said:
			
		

> But since you know that it will not be built in, always use the standalone command.



Well if the which command is not present, the script can not verify the existence of other dependencies, e.g. the external which (in this case) is itself a dependency. Chicken & egg...


----------



## Michael-Sanders (Feb 10, 2013)

Gordon you nailed it, thanks. Just discovered $IFS on my end, was thinking of splitting $PATH with awk which led me right back to the 1st issue (awk is an external dependency itself).

Coming from a WinAPI world, alot to learn on my end still. Lots of folks helping me 'get there'. Its a great community here, really is.


----------



## Michael-Sanders (Feb 10, 2013)

fonz said:
			
		

> I don't know whether it helps at all, but sh(1) also has the built-in command builtin which, when called with a command as argument, returns 0 it it's built-in and non-zero (plus a diagnostic message I can't seem to easily filter out with conventional redirection to /dev/null) if it's not. Example: `% builtin [i]foo[/i] && echo "built-in" || echo "not built-in"`



Hi fonz. Yep, that's exactly what my 1st attempt used (the builtin construct). 

Slowly but surely finding my way around FreeBSD, I appreciate the help & patience you all've shown me =)


----------

