0

We were asked to write a project in shell that should be compatible with every general shell (dash, ksh, bash). We should also cover the possible option that the utility realpath is not available on a particular machine. Is there any easy way how to checks if the utility is present or not?

Saeko
  • 421
  • 1
  • 4
  • 14
  • Just by running it for one ( you can check the return status after to do this automatically). But why would you do that? Just focus on the general solution, as you have to implement it anyway (in case `realpath` fails). Also, what about `csh`? are the 3 you listed the only shells you have to support? – kabanus Mar 25 '18 at 13:08
  • @kabanus : csh is out of question, for two reasons: Saeko would have mentioned it, and, more importantly, she is searching for a *general* solution, i.e. a piece of code working for every shell. Since csh has a completely different syntax from the other shells, this would not be feasible anyway. I think was Saeko is really searching for (because dash is in the list) is a Posix-compatible solution. She made this also clear by using the 'shell' tag for her post. – user1934428 Mar 26 '18 at 06:10
  • @Saeko: Please clarify what "availability" means: That `realpath` is *somewhere* in the file system and has read-permission (which would be expensive to check, but not impossible), or whether it is in the PATH? – user1934428 Mar 26 '18 at 06:12
  • @user1934428 Good point, I never noticed shell defaults to POSIX compliant. My first thoughts were a compiled C program, but it occurred to me that seems to out of scope. – kabanus Mar 26 '18 at 09:25

2 Answers2

1

Checking if an executable is available can be done in several ways. One simple way is to just run it, and check the return code. If you don't want to see the error, redirect it:

realpath yourArgument 2> /dev/null
echo $?

Or in a if:

realpath yourArgument 2> /dev/null
if [ $? -eq 127 ]; then
    #Realpath is missing!
fi

This way if realpath worked and is in the path you will have the real path printed, otherwise you enter the if. Note 0 is the agreed upon success status, adn 127 is the error code indicating missing command (Thanks @user1934428, I used previously -gt 0 which may fail since realpath may return non-0 status.)

kabanus
  • 24,623
  • 6
  • 41
  • 74
  • This won't work, because status code greater than zero is also returned by `realpath` on occasion. Try for instance `realpath /foo/bar/baz`. You could explicitly test for status code equal 127. – user1934428 Mar 26 '18 at 13:18
  • @user1934428 Correct, good catch. I thought about using `which` as well, but I'm guessing OP wants minimum non-shell stuff. – kabanus Mar 26 '18 at 13:28
  • Maybe `which` is not a bad idea at all. It is non-shell in Posix shells (/usr/bin/which), where it searches the path. The only possible drawback could be that if run in bash or zsh, it does not only search the path, but also reports aliases and functions. With other words: A shell function *realpath* would be found in, i.e., bash, but not in Posix shell. In the concrete case of *realpath*, this is perhaps not really a problem. Also, which reports (by status code > 0) that the program has not been found. – user1934428 Mar 27 '18 at 07:22
0

If I did not understand bad, you want to know whether a certain utility exists to check if a directory exists?. If so, I have used this line always in several shells and I have not found problems.

if [ -d "$DIRECTORY" ]; then
    # Control will enter here if $DIRECTORY exists.
fi