如何测试 $PATH 中是否存在应用程序?

如何测试 $PATH 中是否存在应用程序?

我正在尝试编写所有sh启动/环境脚本以尽可能多地使用干燥并尽可能多地:“适用于我将其克隆到的每个 *nix”。这意味着确保如果我尝试运行不存在的代码,该代码会正常失败。为此,我需要能够测试程序是否存在。我知道如何测试文件是否存在,但我不确定如何测试应用程序在路径中是否可执行。我宁愿使用 $PATH,因为其中一些需要在 arch、ubuntu 和 centos 上工作。有些可能安装在我的主目录中,在我没有 root 的系统上,其他可能不会安装,还有一些可能安装在系统路径中。

答案1

使用type commandname。如果有任何可执行文件,则返回 true commandname:别名、函数、内置或外部命令(在 中查找$PATH)。或者,使用command commandnamecommandname如果是内置或外部命令(在 中查找),则返回 true $PATH

exists () {
  type "$1" >/dev/null 2>/dev/null
}

有一些 sh ​​变体(绝对是 POSIX 之前的;我知道/bin/sh在 OSF1 ≤3.x 下以及早期 NetBSD 版本和一些 20 世纪 Linux 发行版中发现的 Almquist shell 的某些版本)总是type返回 0 或不返回存在。我认为本世纪没有任何系统附带这些。如果您遇到过它们,您可以使用以下功能来$PATH手动搜索:

exists () { (
    IFS=:
    for d in $PATH; do
      if test -x "$d/$1"; then return 0; fi
    done
    return 1
) }

如果您想排除内置函数和函数并在$PATH.大多数 shell 都有一个内置的功能,command -v,尽管它是 POSIX 的一个相对较新的补充(从 POSIX:2004 开始仍然是可选的)。它基本上是 的程序员友好版本type:它打印 中可执行文件的完整路径$PATH、内置函数或函数的裸名称以及别名的别名定义。

exists_in_path () {
  case $(command -v -- "$1") in
    /*) return 0;;
    alias\ *) return 1;; # alias
    *) return 1;; # built-in or function
  esac
}

Ksh、bash 和 zsh 也必须type -p仅查找$PATH.注意,在 bash 中,如果是内置 or 函数,则返回状态type -p foo为 0 ;foo如果您想测试 中的可执行文件$PATH,则需要检查输出是否不为空。type -p不在 POSIX 中;例如 Debian 的 ash(在/bin/shUbuntu 上)就没有它。

答案2

如果您只是寻找外部程序,也可以使用which。但不知道它有多便携。

相关内容