解决 Zsh Command not found 的问题

前段时间电脑出问题了,经过反复重装也没能解决,最后只能尝试格式化,没想到真的搞好了。重装之后的电脑所有的功能都要重新安装(是的,之前我有两年没备份),然后就出现了一个让我意外的问题:

  • 我用 homebrew 安装了 autojump,用来快速跳转到常用目录,不需要将路径完整输入;
  • 在我通过命令 j 调用 autojump 时,报错 Command not found,就这个过程做了一下 debug

Shell 是什么

  • Unix 中,用户通过 Shell 命令行界面与系统进行交互。用户输入命令,Shell 将这些命令传递给操作系统来执行
  • Shell 支持编写脚本,执行自动化任务
  • 它本质上是一个接口,实现方式有很多种,其中包括 Bash 和 Zsh

什么是 Bash 和 Zsh

  • Shell 的可用程序有很多种,比如
    • sh:早期的 Shell
    • Bash: sh 的增强版,是 Linux 系统的默认 Shell
    • Zsh: 比 bash 功能更多的 Shell
    • csh:语法类似 C 语言的 Shell
    • ksh:结合了 sh 和 csh 优点的 shell
  • 因此,Bash 和 Zsh 都是流行的 Shell 实现
  • 我现在是在 Mac 中用 Zsh 替代 Bash

Mac 的默认 Shell

  • 我很早使用 iTerm 的时候,按照网上的教程下载了 zsh 和 oh_my_zsh 主题,这次还是这样操作了
  • 但 ChatGPT 说从 Catalina (10.15) 开始,macOS 的默认 Shell 就从 Bash 改成了 Zsh,也就是说我的这个步骤并不必要
  • 可以通过如下命令来看系统当前使用的 Shell 是什么:
    1
    echo $SHELL
  • 如果输出包含 /bin/zsh 就是使用的 Zsh;如果包含 /bin/bash,就是使用的 Bash
    Alt|200
  • 可以看到我现在使用的就是 zsh

为什么会 Command not found

  • 我的第一反应是 Path 设置不对,这一点到底是什么原理其实我没弄清
  • 我尝试问 ChatGPT,它的第一个猜测是没有安装。但我确定昨天执行过 brew install autojump,只是我的确没有仔细看安装后的信息
  • 我进行了如下两个步骤来验证问题出在哪里

如何验证 Path 是否有问题

  • 按理说,如果是 path 问题,应该所有的命令都无法执行,我尝试执行了两个命令:
    1. ls 是系统默认的命令,看起来没问题
    2. python
      |200
      • 第一次还是报错了,让我怀疑还是 path 问题
      • 接着 ChatGPT 提醒我 python 3.x 版本的命令需要使用 python3,而我记得 macOS 新系统是默认安装 python 以及版本是 3.x 的,于是再次尝试
        200
      • 这次没问题了
  • 这样看来并不是 path 导致的问题

如何验证是否下载成功

  • brew info [package] 可以查看 package 的相关信息,以及电脑中是否安装了该应用
  • 可以看到目前是没有安装的状态
  • 但我尝试了另一个命令 brew --prefix [package],这个命令用于查询 Homebrew 的安装路径
    200
  • 可以看到是有路径的,问了 ChatGPT,应该是尝试安装,但是安装失败之后遗留的文件

解决方案

升级 python 到符合 autojump 的 dependencies

  • 先将 python 升级到 autojump 要求的 3.13
  • 查了一下 Python 的文档,目前最新版本的 stable version 就是 3.13
  • 通过 brew install python 下载
  • 下载成功后,python3 --version 返回的还是原来的版本
  • .zshrc 中添加配置,修改 path
    1
    export PATH="/usr/local/opt/python@3.13/bin:$PATH"
  • 这里做的调整是,path 里的路径是我通过 brew --prefix python 获取的
  • 通过 source ~/.zshrc 重新加载配置
  • 之后系统就会默认使用 3.13 版本的 python
    300
  • 然后再下载 autojump brew install autojump,之后就可以使用 j