如何在 Linux 上使用 which 命令

理解Linux中的 which 命令

在Linux系统中,当你通过shell执行命令时,which命令可以帮助你定位该命令对应的可执行二进制文件。如果你的系统安装了同一程序的多个版本,which能告诉你shell将要使用哪一个。

二进制文件与路径

当我们从终端运行程序或命令时,shell(例如现代发行版中常见的 Bash)必须先找到这个命令并执行。一些命令,如 cdhistorypwd,是内置于shell中的,Bash可以直接调用。

那么,Bash是如何找到其他外部命令、程序和独立二进制文件的呢?它通过“路径”来查找。路径实际上是一系列目录的集合,Bash会依次在这些目录中查找与你输入的命令相匹配的可执行文件。一旦找到,Bash就会执行它并停止搜索。

你可以通过查看 $PATH 环境变量来了解路径中包含哪些目录。在终端中输入以下命令,然后按回车键:

echo $PATH

输出结果会列出多个路径,每个路径用冒号(:)分隔。在示例系统中,Bash会按照以下顺序搜索目录:

/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/user/games
/usr/local/games
/snap/bin

值得注意的是,文件系统中存在多个名为/sbin/bin的文件夹,这可能会造成一些混淆。

理解路径的重要性

假设我们有一个名为htg的程序的升级版本,它位于当前目录。我们可以通过输入以下命令来运行它:

./htg

这个程序的作用仅仅是打印版本号,然后退出。新版本号是1.2.138。

要在当前工作目录中运行程序,你必须在程序名前加上./,以便Bash知道在哪里找到它。

为了能够在任何目录下运行这个程序,我们将可执行文件移动到 /usr/bin 目录。这样,Bash就可以在路径中找到它并执行。

我们不再需要当前目录下的可执行文件,也不需要在程序名前输入./,操作如下:

sudo mv htg /usr/bin

现在,我们尝试直接运行程序:

htg

程序确实运行了,但是它不是我们期望的新版本,而是旧版本1.2.105。

which 命令的作用

我们遇到的问题正是 which 命令 设计的目的

在这个例子中,我们将使用 which 命令,并将我们想要调查的程序名称作为参数传递:

which htg

输出结果显示,htg 版本位于/usr/local/bin目录中。由于该目录在我们的新版本htg所在的目录之前被搜索,Bash会优先执行旧版本。

如果我们使用 -a(all)选项,即使找到匹配项也会继续搜索:

which -a htg

现在,它会列出路径中所有匹配的程序。

问题在于,路径中存在较早版本的程序,且该目录在包含新版本程序的目录之前被搜索。

为了验证,我们可以显式地运行每个版本的程序:

/usr/local/bin/htg
/usr/bin/htg

这清楚地说明了问题,解决方案也很简单。 我们可以删除 /use/local/bin 目录中的旧版本,也可以将/usr/bin 中的新版本移动到 /usr/local/bin

which 命令的更多细节

which 命令的结果并不总是代表有两个独立的二进制文件。

我们用 -a (all) 选项来查找 less 程序的情况:

which -a less

输出结果报告有两个 less 程序的版本。但这是真的吗?在同一台 Linux 机器上安装两个版本的 less(或同一版本的两个不同位置)是不寻常的。让我们深入研究一下。

我们可以使用 ls 命令的 -l(长列表)和 -h(人类可读)选项来查看究竟发生了什么:

ls -lh /usr/bin/less

显示的文件大小为九个字节!这绝对不是 less 的完整副本。

列表的第一个字符是l。普通文件的第一个字符是连字符(-)。这里的 l 表示这是一个符号链接。-> 符号也表明这是一个符号链接,你可以把它理解为快捷方式。这个符号链接指向 /bin 目录下的 less 程序。

我们再来看看 /bin 目录下的 less 版本:

ls -lh /bin/less

这个结果显示,这确实是一个真正的可执行二进制文件。 列表的第一个字符是连字符(-),表示它是一个常规文件,且文件大小为167 KB。因此,系统只安装了一个 less 程序,但有一个从另一个目录指向它的符号链接,当 Bash 搜索路径时,也会找到这个链接。

一次检查多个命令

which 命令可以同时检查多个程序,它会按照你提供的顺序逐个查找。

例如,如果你输入:

which ping cat uptime date head

它会依次处理你提供的程序列表,并列出每个程序的结果。

which 命令的自我检查

你甚至可以使用 which 命令来检查它本身:

which which

除了探索 Linux 文件系统,当你期望某个命令或程序表现出一种行为,但实际却是另一种行为时,which 命令非常有用。 它可以帮助你验证 Bash 正在执行的是你期望的命令。