从零开始
目录

02 · 操作系统 · macOS

认识 Shell:zsh 与环境变量

本篇你将学到

  • 终端和 shell 有什么区别,zsh 和 bash 是什么关系
  • 怎么看自己用的是哪个 shell,怎么换
  • 环境变量和 PATH:为什么会 command not found
  • ~/.zshrc 配置文件、别名、历史记录、Tab 补全

Shell:终端里的“翻译”

上一篇(02-14)打开的“终端”只是个窗口,负责显示文字、接收键盘输入。真正读懂你的命令、去执行它的,是窗口里运行的另一个程序:shell。打个比方,终端是电话机,shell 是电话那头帮你办事的接线员。

shell 既是命令解释器(你说一句,它做一件),也是一门简单的编程语言,可以把一串命令写成脚本[1]。它还带着很多方便手动操作的功能,比如命令行编辑、历史记录、别名[1],下面会一个个讲。

zsh 和 bash

shell 有好几种,最常见的是 zsh 和 bash:

  • 从 macOS 10.15 起,新建的用户默认用 zsh;10.14 及更早默认用 bash[2]。
  • zsh 和老牌的 sh 高度兼容,和 bash 大部分兼容,只有少数区别[2]。日常用的 cd、ls、export 写法都一样。
  • Linux 上更常见的是 bash(见 02-23)。

看看你用的是哪个:

echo $SHELL

显示 /bin/zsh 就是 zsh。$SHELL 是一个环境变量,下面马上讲。

想换 shell(一般不需要):

  • 命令行:chsh -s /bin/bash,路径必须是 /etc/shells 文件里列出的某一个,比如 /bin/zsh、/bin/bash[2][3];
  • 图形界面(macOS 13 及以后):系统设置 → 用户与群组,按住 Control 点你的用户名,选“高级选项”,在“登录 shell”菜单里选[2]。

换完后新开的终端窗口才会用新的 shell。在新版 macOS 上用 bash,会看到一行提示说默认 shell 已经是 zsh 了[2],这是正常的。

环境变量与 PATH

环境变量像贴在电脑上的便利贴,每张写着“名字=内容”,系统和程序需要时来看一眼。比如:

echo $HOME      # 你的家目录,比如 /Users/xiaoming
echo $SHELL     # 你的 shell
echo $PATH      # 去哪些文件夹找命令
env             # 列出全部环境变量

在名字前加 $,shell 就把它换成内容。macOS 上环境变量的名字分大小写,$PATH 和 $Path 是两个变量[4]。

最重要的是 PATH:一串用冒号 : 隔开的文件夹[4]。

/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

你输入 ls,shell 就从左到右挨个文件夹去找叫 ls 的程序,找到第一个就执行,后面的不再看[5]。像查通讯录:通讯录里没有这个人,就打不出去。程序明明在电脑上,可它所在的文件夹不在 PATH 里,就会看到:

zsh: command not found: hello

两种解决办法:写完整路径(~/tools/hello),或者把 ~/tools 这个文件夹加进 PATH。

临时设置:export

export PATH="$HOME/tools:$PATH"

意思是:新的 PATH = ~/tools + 冒号 + 原来的 PATH。export 表示把这个变量交给从这个 shell 启动的程序[5]。

这样改只管当前这个窗口,关掉就没了。

千万别写成 export PATH="$HOME/tools":漏了后面的 :$PATH,原来的文件夹全没了,连 ls 都会找不到。写错了也别慌,关掉窗口重新开一个就恢复了。

永久设置:~/.zshrc

zsh 每次启动都会读几个配置文件,按顺序执行里面的命令[6]。最常用的两个:

文件 什么时候读
~/.zprofile 登录时,包括用 SSH 远程登录[2]
~/.zshrc 每次新开一个终端窗口[2]

所以想让设置一直有效,就把那句 export 写进 ~/.zshrc。文件名以 . 开头,是隐藏文件,ls 看不到,要用 ls -a。最简单的写法是往文件末尾追加一行:

echo 'export PATH="$HOME/tools:$PATH"' >> ~/.zshrc

>> 是“追加到末尾”。**注意只有一个 > 会把整个文件覆盖掉!**也可以用 nano ~/.zshrc 在终端里打开编辑(Control-O 保存,Control-X 退出)。

写进去以后,新开的窗口会自动生效;想让当前窗口也生效,运行:

source ~/.zshrc

后面装 Homebrew 时(02-17),要往 ~/.zshrc 里加的那行 eval "$(/opt/homebrew/bin/brew shellenv)",做的也是同一件事:把 Homebrew 的文件夹加进 PATH。

以前用 bash 的人:.zprofile 对应 bash 的 .bash_profile,.zshrc 对应 .bashrc[2],export 这类设置可以原样搬过来[2]。

别名:给长命令起外号

alias ll='ls -l'

以后输入 ll,shell 就把它换成 ls -l 再执行[7]。直接输入 alias 列出所有别名,unalias ll 删掉。zsh 自己不带任何预设的别名[5],都是你自己加的。同样,想一直有效就写进 ~/.zshrc。

历史记录和 Tab 补全

  • ↑ 方向键翻之前的命令(上一篇讲过);输入 history 列出最近的命令。
  • Tab 键自动补全:输入命令或文件名的开头,按 Tab,shell 帮你补全剩下的[5];有好几个可能时,会把候选都列出来。比如 cd Doc 按 Tab,变成 cd Documents/。zsh 的补全系统很强,在终端里输入 man zsh 可以看详细说明[2]。

少打字,也少打错字。

Oh My Zsh:可选,先别急

网上常推荐 Oh My Zsh:一个社区维护的 zsh 配置框架,带几百个插件和主题[8]。它不是必需的,新手先把本篇的基本功练熟再说。真要装,注意:

  • 安装方式是运行一段从网上下载的脚本。官方也建议:对不熟悉的项目,先把脚本下载下来看一遍,再运行[9];
  • 安装会把你原来的 ~/.zshrc 改名为 ~/.zshrc.pre-oh-my-zsh[9],之前加的设置要自己搬回新的 ~/.zshrc;
  • 不想用了,运行 uninstall_oh_my_zsh 可以卸载并恢复原来的配置[9]。

动手模拟

在模拟的 zsh 里体验一遍:command not found → 临时加 PATH → 新开窗口又没了 → 写进 ~/.zshrc 永久生效。最后练练别名、Tab 补全和历史。

模拟实操 · zsh:PATH、配置文件与别名纯模拟,命令不会真的执行

    可以直接打字,也可以点上面的命令按钮把命令填进去,再按回车(或点“运行”)。↑ 键翻出上一条命令。按 Tab 键(手机上点“Tab ⇥”)自动补全。“新开一个终端窗口”会像真的一样重新开始:临时设置会消失,配置文件和历史记录会保留。输入 help 看看支持哪些命令。

    小结

    • 终端是窗口,shell 是解释命令的程序;macOS 默认 zsh,echo $SHELL 查看,chsh -s 更换。
    • PATH 是冒号隔开的文件夹列表,从左到右找命令;找不到就 command not found。
    • 临时:export PATH="$HOME/tools:$PATH";永久:写进 ~/.zshrc,新开窗口或 source ~/.zshrc 生效。
    • alias 起外号,history 看历史,Tab 自动补全。

    参考资料

    1. [1]Bash Reference Manual: What is a shell? · GNU
      https://www.gnu.org/software/bash/manual/html_node/What-is-a-shell_003f.html
    2. [2]Use zsh as the default shell on your Mac · Apple 支持
      https://support.apple.com/en-us/102360
    3. [3]chsh(1) · man7.org(util-linux)
      https://man7.org/linux/man-pages/man1/chsh.1.html
    4. [4]about_Environment_Variables · Microsoft Learn(PowerShell,含 macOS/Linux 说明)
      https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_environment_variables
    5. [5]A User's Guide to the Z-Shell, Chapter 3 · zsh.sourceforge.io
      https://zsh.sourceforge.io/Guide/zshguide03.html
    6. [6]zsh Manual: Files(Startup/Shutdown Files) · zsh.sourceforge.io
      https://zsh.sourceforge.io/Doc/Release/Files.html
    7. [7]Bash Reference Manual: Aliases · GNU
      https://www.gnu.org/software/bash/manual/html_node/Aliases.html
    8. [8]Oh My Zsh · ohmyz.sh
      https://ohmyz.sh/
    9. [9]ohmyzsh/ohmyzsh README · GitHub
      https://github.com/ohmyzsh/ohmyzsh