如果您想知道某个命令名称在当前 Mac 终端会话中会运行哪个程序,请先询问 zsh 如何解释该名称,然后在 PATH 中搜索可执行文件。这一点很重要,因为在 shell 查找到文件之前,命令可能会先解析为别名或 shell 函数。在 macOS 上,终端的默认 shell 是 zsh,不过终端配置文件或管理员可以选择其他 shell。Apple 终端指南
询问 zsh 该命令名称的含义
在终端中,运行带有该命令名称的 whence -v,不要带任何会执行该命令的参数。例如:
whence -v python3
输出会指明 zsh 将使用的命令类型:它可能会报告别名(alias)、函数(function)、内置命令(builtin)或外部命令(external command)。如果报告为别名或函数,该名称并不能直接指明将要运行的可执行文件;别名或函数可能会展开为另一个命令或运行多个命令。zsh 文档指出 whence 是一种用于报告如何解释名称的方法。zsh shell 内置命令文档
如需获取精简的类型标签,请使用:
whence -w python3
如果结果是 function,请使用 functions python3 检查其定义。如果是 alias,请使用 alias python3 进行检查。这些命令会显示当前 shell 中的定义;它们不会执行目标程序。函数可能会调用另一个函数或外部程序,因此请跟踪其定义,直到找到执行实际工作的命令为止。
在 PATH 中查找可执行文件
即使别名或函数遮蔽了该名称,若要查找 zsh 通过 PATH 定位的文件,请使用:
whence -p python3
若要列出每个匹配的 PATH 条目,请使用:
whence -pa python3
-p 选项让 zsh 忽略 shell 层级的定义去搜索 PATH,而 -a 则报告所有匹配项,而不仅仅是第一个。第一个 PATH 匹配项就是 zsh 在常规外部命令查找中所能找到的可执行文件。zsh 还可以通过 whence -ps python3 显示符号链接的解析路径。zsh shell 内置命令文档
PATH 列表属于当前 shell 环境。使用 print -r -- $PATH 可以查看其中的目录;zsh 以冒号分隔值的形式呈现其 path 参数。PATH 顺序的改变可能会改变优先找到的同名项。Apple 将 PATH 描述为 shell 搜索命令的目录列表,并指出 shell 环境设置与其特定的执行上下文相关。Apple:在 Mac 上的“终端”中使用环境变量
检查命令的调用方式
带有斜杠的命令(例如 ./python3 或 /opt/tools/python3)指定的是路径,而不是要求 shell 在 PATH 中搜索该名称。相对路径 ./python3 表示当前目录中的文件。Apple 的命令行入门指南解释说,不带前导斜杠的名称在用作路径时是相对于当前目录的,而 ./ 则显式运行当前目录下的程序。Apple:命令行入门
对于像 python3 这样的普通名称,请同时检查其 shell 类型和 PATH 匹配项。对于包含 / 的路径,请检查那个确切的文件。运行包含空格或 shell 元字符的路径时,请将其用引号引起来;例如 "/Applications/Tool Folder/tool"。Apple 的入门指南记录了在路径中给特殊字符加引号或转义的方法。这样可以在不改变命令运行方式的情况下定位所调用的文件。
了解此查找方式无法证明的内容
查找结果仅说明当前 shell 的解析情况,并不代表所有执行上下文。另一个终端窗口可能具有不同的 PATH 或 shell 设置,而且命令在脚本、其他 shell 或终端之外启动的应用程序中可能表现不同。Apple 指出,终端窗口之间不共享 shell 环境。Apple:在 Mac 上的“终端”中使用环境变量
此外,仅找到路径名本身并不能证明它就是所有情况下最终使用的进程:该文件可能是符号链接、启动另一个程序的脚本,或是启动器。whence -ps 可以揭示符号链接的解析结果,但要追踪脚本的进一步行为,则需要检查该脚本或该程序的文档。如果 whence -p 没有返回任何路径,说明该名称在此 shell 中没有 PATH 匹配项;但它仍可能是一个别名、函数、内置命令,或者是只能通过显式路径使用的命令。
日常检查时,可先运行 whence -v name,检查所有别名或函数,然后使用 whence -pa name 比较候选的可执行文件。这一顺序既能弄清 zsh 能识别出什么,又能确定其 PATH 搜索会找到哪个文件。
参考资料
在 Mac 上的“终端”中更改默认 Shell — Apple 支持
Shell 内置命令 — The Z Shell
在 Mac 上的“终端”中使用环境变量 — Apple 支持
命令行入门 — Apple Developer