SoFunction
Updated on 2025-03-02

The shell script used to detect whether the entered option $1 is in the PATH

Today I accidentally found a very interesting book about shell programming. It is in e-text and contains 101 shell cases. I insist on reading one tomorrow and writing some experiences.
Here is example 001:

#!/bin/sh
# inpath - Verifies that a specified program is either valid as is,
#  or that it can be found in the PATH directory list.

in_path()
{
 # Given a command and the PATH, try to find the command. Returns
 # 0 if found and executable, 1 if not. Note that this temporarily modifies
 # the IFS (input field separator) but restores it upon completion.

 cmd=$1    path=$2     retval=1
 oldIFS=$IFS  IFS=":"

 for directory in $path
 do
  if [ -x $directory/$cmd ] ; then
   retval=0   # if we're here, we found $cmd in $directory
  fi
 done
 IFS=$oldIFS
 return $retval
}

checkForCmdInPath()
{
 var=$1

 # The variable slicing notation in the following conditional
 # needs some explanation: ${var#expr} returns everything after
 # the match for 'expr' in the variable value (if any), and
 # ${var%expr} returns everything that doesn't match (in this
 # case, just the very first character. You can also do this in
 # Bash with ${var:0:1}, and you could use cut too: cut -c1.

 if [ "$var" != "" ] ; then
  if [ "${var%${var#?}}" = "/" ] ; then
   if [ ! -x $var ] ; then
    return 1
   fi
  elif ! in_path $var $PATH ; then
   return 2
  fi
 fi
}

 
if [ $# -ne 1 ] ; then
 echo "Usage: $0 command" >&2 ; exit 1
fi

checkForCmdInPath "$1"
case $? in
 0 ) echo "$1 found in PATH"         ;;
 1 ) echo "$1 not found or not executable"  ;;
 2 ) echo "$1 not found in PATH"       ;;
esac

exit 0

This script is intended to detect whether the input option $1 is in PATH.


There are several things worth noting about this script:
1) It uses function nesting and nests the in_path function in checkForCmdInPath.
2) if [ "${var%${var#?}}" = "/" ] The ${var%${var#?}} in this statement is the first character of the display variable, and can also be replaced by ${varname:1:1} or $(echo $var | cut -c1).
3) elif ! in_path $var $PATH ; then this means if the execution result of in_path $var $PATH is not 0
question:
It is found that the inputs echo , echo_err , /etco_err all return the correct results, but the input /etc/echo_right (there is an execution file but is not in the PATH) returns found in PATH. I think there is still something to be perfected in this script.