更新

更新

PATH我需要使用 shell 脚本找到给定程序的路径。该路径必须是程序的实际完整路径,稍后可以将其传递给函数之一exec*,该函数不会搜索PATH自身,例如execv

有一些程序,例如kill,它们既可以作为实际程序使用,又可以同时作为内置 shell 使用。如果是这种情况,我需要实际程序的完整路径。

有几个实用程序可以找到PATH指定的程序第 2.9.1.1 节, POSIX 标准的命令搜索和执行

which,它不属于任何标准。它可以是某些系统上的常规程序,而某些 shell 提供它是内置程序。它似乎在大多数系统和 shell 上都可用,但具有内置版本的 shell 也只返回内置版本的名称,而不是可执行文件的路径。此外,它没有以任何方式标准化,并且可能返回任何输出并采取不同的选项。

bash# which kill
/usr/bin/kill
dash# which kill
/usr/bin/kill
fish# which kill
/usr/bin/kill
mksh# which kill
/usr/bin/kill
tcsh# which kill
kill: shell built-in command.
zsh# which kill
kill: shell built-in command

whence,它是几个shell的内置。但在许多 shell 上不可用。它也将返回内置函数的名称,而不是程序的路径。可以将A-p传递到何处以更改此行为。

bash# whence kill
bash: whence: command not found
dash# whence kill
dash: 1: whence: not found
fish# whence kill
fish: Unknown command 'whence'
mksh# whence kill
kill
mksh# whence -p kill
/usr/bin/kill
tcsh# whence kill
whence: Command not found.
zsh# whence kill
kill
zsh# whence -p kill
/usr/bin/kill

有的是commandPOSIX:2008 指定的内置。不幸的是,它还会搜索常规命令和内置命令,并将返回内置命令的名称,而不是返回由同名内置命令隐藏的程序的路径。一些旧的 shell 还没有实现它。

bash# command -v kill
kill
dash# command -v kill
kill
fish# command -v kill
/usr/bin/kill
mksh# command -v kill
kill
tcsh# command -v kill
command: Command not found.
zsh# command -v kill
kill

答案1

你自己去找找吧。

export IFS=":"
[ -z "${1}" ] && exit 1
for dir in $PATH
do if [ -x "${dir}/${1}" ]
   then echo "${dir}/${1}"
        exit 0
   fi
done
echo ${1} not found
exit 1

测试于bash, dash, ksh, mksh,zsh

更新

上面的内容对于独立脚本来说很好,但是如果您计划将其嵌入到更大的脚本中,您可能需要使用更像下面的内容。

function find_path() {
   IFS_SAVE="${IFS}"
   export IFS=":"
   [ -z "${1}" ] && return 1
   for dir in $PATH
   do if [ -x "${dir}/${1}" ]
      then echo "${dir}/${1}"
           export IFS="${IFS_SAVE}"
           return 0
      fi
   done
   export IFS="${IFS_SAVE}"
   echo ${1} not found
   return 1
}

这是为了IFS在找到匹配后恢复,也将exit's 与return's交换

相关内容