理解Linux中的 which 命令
在Linux系统中,当你通过shell执行命令时,which
命令可以帮助你定位该命令对应的可执行二进制文件。如果你的系统安装了同一程序的多个版本,which
能告诉你shell将要使用哪一个。
二进制文件与路径
当我们从终端运行程序或命令时,shell(例如现代发行版中常见的 Bash)必须先找到这个命令并执行。一些命令,如 cd、history 和 pwd,是内置于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 正在执行的是你期望的命令。