为什么“which”在我可以运行的某些命令上不返回任何内容?

Pen*_*ang 23 bash

我曾经which告诉过一个可运行文件的位置。例如,which pwd返回/bin/pwd. 但是,我发现which aliasorwhich compgen等什么都不返回。

命令是什么样的alias?它们不是我的 Linux 上的可执行文件吗?我在 Ubuntu 上使用 bash 4.3。

Joh*_*024 35

我发现which aliaswhich compgen等什么都不返回。

这两个都是 shell 内置函数。 which对 shell 内置函数一无所知:它只是搜索可执行文件的路径。

要获得更可靠的结果,请使用type

$ type compgen
compgen is a shell builtin
$ type alias
alias is a shell builtin
Run Code Online (Sandbox Code Playgroud)

type 对执行的内容有更好的了解,因为它是一个内置的 shell。

为什么which不可靠

which经常给出错误的答案。观察:

$ type pwd
pwd is a shell builtin
$ which pwd
/bin/pwd
Run Code Online (Sandbox Code Playgroud)

当您运行 时pwd,没有指定显式路径,shell 将执行其内置程序,而不是which找到的可执行文件。

以下是which给出错误答案的更多示例:

$ type echo
echo is a shell builtin
$ which echo
/bin/echo
$ type [
[ is a shell builtin
$ which [
/usr/bin/[
Run Code Online (Sandbox Code Playgroud)

观察:

$ type /bin/echo
/bin/echo is /bin/echo
Run Code Online (Sandbox Code Playgroud)

当您为 提供显式路径时echo,例如/bin/echo,shell 将运行该可执行文件,而不是其内置文件。 type也知道这一点,正如您在上面看到的那样。

which内部如何运作

在类似 debian 的系统上,which是一个简单的 shell 脚本,其中的相关部分是:

   for ELEMENT in $PATH; do
    if [ -z "$ELEMENT" ]; then
     ELEMENT=.
    fi
    if [ -f "$ELEMENT/$PROGRAM" ] && [ -x "$ELEMENT/$PROGRAM" ]; then
     puts "$ELEMENT/$PROGRAM"
     RET=0
     [ "$ALLMATCHES" -eq 1 ] || break
    fi
   done
Run Code Online (Sandbox Code Playgroud)

如您所见,它会沿着 PATH 进行简单的搜索,以查找给定名称的可执行文件。

  • 是的,这就是为什么它可以了解其他 shell 内置函数的原因。在大多数机器上,`which` 只是一个简单的脚本。 (2认同)
  • 或者只使用`cat \`which which\`` (2认同)