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 补全和历史。
可以直接打字,也可以点上面的命令按钮把命令填进去,再按回车(或点“运行”)。↑ 键翻出上一条命令。按 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]Bash Reference Manual: What is a shell? · GNU
https://www.gnu.org/software/bash/manual/html_node/What-is-a-shell_003f.html - [2]Use zsh as the default shell on your Mac · Apple 支持
https://support.apple.com/en-us/102360 - [3]chsh(1) · man7.org(util-linux)
https://man7.org/linux/man-pages/man1/chsh.1.html - [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]A User's Guide to the Z-Shell, Chapter 3 · zsh.sourceforge.io
https://zsh.sourceforge.io/Guide/zshguide03.html - [6]zsh Manual: Files(Startup/Shutdown Files) · zsh.sourceforge.io
https://zsh.sourceforge.io/Doc/Release/Files.html - [7]Bash Reference Manual: Aliases · GNU
https://www.gnu.org/software/bash/manual/html_node/Aliases.html - [8]Oh My Zsh · ohmyz.sh
https://ohmyz.sh/ - [9]ohmyzsh/ohmyzsh README · GitHub
https://github.com/ohmyzsh/ohmyzsh