Linux which 命令:定位命令位置

LinuxBeginner
立即练习

简介

在本实验中,你将学习如何使用 which 命令来查找 Shell 在执行某个命令时实际运行的可执行文件。你将检查已安装的命令、处理不可用的命令、列出多个匹配项,并观察 PATH 环境变量如何影响搜索结果。

为了让你更容易理解 which 的工作原理,本实验还引入了一些辅助性的 Shell 概念,例如简单的脚本编写、可执行权限以及临时修改 PATH。每个新概念都会在相应位置进行解释,以便你专注于理解为什么 which 会返回特定的路径。

理解 which 的基础知识

当你入职 TechCorp 后,团队负责人要求你核实一些关键开发工具的安装情况。which 命令将是你完成此任务的首选工具。

which 命令用于通过搜索 PATH 环境变量中列出的目录,来定位与给定命令关联的可执行文件。

让我们先从定位 gcc 编译器开始:

which gcc

你应该会看到类似以下的输出:

/usr/bin/gcc

此输出告诉你 gcc 可执行文件位于 /usr/bin 目录下。这意味着当你在终端输入 gcc 时,系统将执行位于 /usr/bin/gcc 的文件。

现在,让我们尝试定位另一个必备工具 python

which python

你可能会看到类似这样的结果:

/usr/local/bin/python

which 命令会搜索 PATH 环境变量中列出的目录,并返回它找到的第一个匹配项。如果你看到的路径不同,不必担心——这只是意味着 Python 在你系统上的安装位置不同而已。

处理不存在的命令

团队负责人提到 TechCorp 过去使用过一种名为 techbuild 的自定义构建工具。让我们检查一下它是否仍然安装:

which techbuild

你可能看不到任何输出(Bash Shell),或者可能会看到类似 techbuild not found 的错误消息(Zsh Shell)。

这是因为如果 which 无法在你的 PATH 中找到该命令,它就不会返回任何内容。不要因为没有输出而感到惊慌——这是该命令在告诉你 techbuild 不在你的 PATH 目录列表中。

为了更直观地展示这种行为,我们可以使用一个简单的 Shell 脚本。这里我们将引入两个新概念:

  1. Shell 脚本是一个文本文件,用于按顺序存储和运行命令。
  2. cat <<'EOF' ... EOF 模式可以将多行内容写入文件,而无需处理复杂的嵌套引号。

让我们创建一个脚本来检查 techbuild

cat > ~/check_techbuild.sh <<'EOF'
#!/bin/bash
if which techbuild >/dev/null 2>&1; then
  echo "techbuild is installed"
else
  echo "techbuild is not installed"
fi
EOF

此命令创建了一个名为 ~/check_techbuild.sh 的文件,并向其中填充了一个简单的 Bash 脚本。

以下是关键行的含义:

  • #!/bin/bash 告诉 Linux 使用 Bash 运行该脚本。
  • which techbuild 检查该命令是否可以在你的 PATH 中找到。
  • >/dev/null 2>&1 会隐藏正常输出和错误输出,以便脚本能够打印出自己清晰的结果信息。

现在为该文件赋予执行权限并运行它:

chmod +x ~/check_techbuild.sh

chmod +x 命令添加了执行权限,允许 Linux 将该文件作为命令运行。

~/check_techbuild.sh

该脚本会打印 techbuild is not installed,因为 which 找不到该命令。

发现多个安装版本

随着你继续配置环境,你发现 TechCorp 在不同项目中使用多个版本的 Python。which-a 选项可以帮助你发现命令的所有安装位置:

which -a python

你可能会看到如下输出:

/usr/local/bin/python
/usr/bin/python
/bin/python

此输出表明系统上存在多个 Python 安装版本。-a 选项告诉 which 打印 PATH 中所有匹配的可执行文件,而不仅仅是第一个。

理解这一点至关重要,因为它向你展示了根据 PATH 配置可能运行的所有 Python 可执行文件。列表中第一个显示的路径,就是你在终端输入 python 时实际执行的文件。

理解 PATH 优先级

团队负责人解释说,PATH 变量中目录的顺序决定了默认使用哪个版本的命令。让我们检查一下你的 PATH:

echo $PATH

你会看到一个以冒号分隔的目录列表。例如:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

顺序很重要:排在前面的目录具有更高的优先级。这意味着如果不同目录中存在两个同名的可执行文件,系统将使用 PATH 中排在前面的那个目录下的文件。

实验环境已经预先在 ~/custom_bin 中创建了一个自定义的 prioritydemo 命令。将该目录添加到 PATH 的最前面,以便它在系统目录之前被检查:

export PATH=$HOME/custom_bin:$PATH

现在检查默认会运行哪个 prioritydemo

which prioritydemo

你应该会看到类似以下的输出:

/home/labex/custom_bin/prioritydemo

要查看 PATH 中所有匹配的 prioritydemo 命令,请运行:

which -a prioritydemo

你应该会先看到你的自定义命令,随后是 /usr/local/bin 中已有的副本:

/home/labex/custom_bin/prioritydemo
/usr/local/bin/prioritydemo

这清晰地展示了 PATH 优先级:which prioritydemo 返回第一个匹配的可执行文件,而 which -a prioritydemo 则按当前的搜索顺序显示所有匹配的可执行文件。

创建自定义命令

团队负责人建议创建一个简单的自定义命令,以演示 which 如何与 PATH 交互。让我们在主目录下创建一个名为 hello 的脚本:

cat > ~/hello <<'EOF'
#!/bin/bash
echo "Hello from TechCorp!"
EOF
chmod +x ~/hello

这会在你的主目录下创建一个名为 hello 的新文件并使其可执行。该脚本运行时会打印 Hello from TechCorp!

现在,尝试运行它:

hello

你会得到一个“command not found”(命令未找到)错误,因为你的主目录不在 PATH 中。PATH 是 Shell 查找可执行文件的目录列表。

让我们临时将你的主目录添加到 PATH 中:

export PATH="$PATH:$HOME"

此命令将你的主目录添加到当前终端会话 PATH 的末尾。export 命令使更新后的 PATH 对后续运行的命令生效。

现在你可以运行 hello 了,which 也能找到它:

hello
which hello

你应该会看到 "Hello from TechCorp!" 以及脚本的路径。这演示了 which 如何在 PATH 中列出的任何目录中查找可执行文件。

总结

在本实验中,你学习了如何使用 which 命令来定位系统 PATH 中的可执行文件。你已经掌握了如何:

  1. 查找已安装程序的位置
  2. 处理不存在的命令
  3. 发现同一命令的多个安装版本
  4. 理解 PATH 优先级
  5. 创建并定位自定义命令

你还练习了编写简单的 Shell 脚本,使用 chmod +x 使文件可执行,并调整 PATH 以控制运行哪个命令。

随着你作为 TechCorp 开发者的职业生涯不断深入,这些技能将变得非常有价值。