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
有的是command
POSIX: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交换