![为什么“which”在我可以运行的某些命令上不返回任何内容?](https://linux22.com/image/865342/%E4%B8%BA%E4%BB%80%E4%B9%88%E2%80%9Cwhich%E2%80%9D%E5%9C%A8%E6%88%91%E5%8F%AF%E4%BB%A5%E8%BF%90%E8%A1%8C%E7%9A%84%E6%9F%90%E4%BA%9B%E5%91%BD%E4%BB%A4%E4%B8%8A%E4%B8%8D%E8%BF%94%E5%9B%9E%E4%BB%BB%E4%BD%95%E5%86%85%E5%AE%B9%EF%BC%9F.png)
我曾经which
告诉过可运行文件的位置。例如,which pwd
返回/bin/pwd
。但是,我发现which alias
或which compgen
等没有返回任何内容。
命令是什么样的alias
?它们不是我的 Linux 上的可执行文件吗?我在 Ubuntu 上使用 bash 4.3。
答案1
我发现
which alias
或which compgen
等什么都没有返回。
这两者都是 shell 内置命令。 which
对 shell 内置命令一无所知:它只是在路径中搜索可执行文件。
为了获得更可靠的结果,请使用type
。
$ type compgen
compgen is a shell builtin
$ type alias
alias is a shell builtin
type
由于它是 shell 内置命令,因此能够更好地了解执行的内容。
为什么which
不可靠
which
经常会给出错误答案。观察:
$ type pwd
pwd is a shell builtin
$ which pwd
/bin/pwd
当您运行 时pwd
,如果不指定明确的路径,shell 将执行其内置命令,而不是which
找到的可执行文件。
以下是更多which
给出错误答案的例子:
$ type echo
echo is a shell builtin
$ which echo
/bin/echo
$ type [
[ is a shell builtin
$ which [
/usr/bin/[
观察:
$ type /bin/echo
/bin/echo is /bin/echo
当您为 提供明确的路径时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
如您所见,它沿着 PATH 进行简单搜索,查找给定名称的可执行文件。
答案2
我认为这是因为没有名为alias
或compgen
等的程序/文件。它们可能只是keywords
BASH 作为语言解释器所知道的。
您可以认为 BASH 是一个程序,并且alias
只是该程序中方法的名称。