我需要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
Run Code Online (Sandbox Code Playgroud)
有whence,它是几个 shell 的内置函数。但在许多外壳上不可用。它也将返回内置程序的名称而不是程序路径。-p可以将A传递给 wherece 以更改此行为。
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
Run Code Online (Sandbox Code Playgroud)
有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
Run Code Online (Sandbox Code Playgroud)
Zac*_*ady 11
自己去寻找就行了。
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
Run Code Online (Sandbox Code Playgroud)
在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
}
Run Code Online (Sandbox Code Playgroud)
这是为了IFS在找到匹配项后恢复,也将exit's 与return's交换