背景

最近在 mac 上安装了 nginx 用来跑本地 web 服务。
但是启动的时候需要切换到 nginx 的安装目录下,然后执行命令才能启动。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 进入 nginx 目录
cd /usr/local/nginx

# 启动 nginx 服务
sudo sbin/nginx

# 退出 nginx
sudo sbin/nginx -s quit

# 强制停止 nginx
sudo sbin/nginx -s stop

# 重启 nginx
sudo sbin/nginx -s reload

可以看到每次操作 nginx 都需要切到对应目录才能执行命令,挺不方便的。
有没有更便捷的方法呢?当然是有的,那就是使用环境变量。

环境变量

环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,如临时文件夹位置、系统文件夹位置以及某些应用软件文件的路径等等。环境变量相当于给系统或用户应用程序设置的一些参数,具体起什么作用这当然和具体的环境变量相关。

比如 Path,是告诉系统,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到哪些目录下去寻找。

环境变量的配置文件

设置的环境变量需要生效,就必须要存起来,存到配置文件里。

在 Mac 中环境变量的配置文件有好几种类型。

系统级别

系统级别配置文件,系统启动就会加载,修改需要 Root 权限。

  • /etc/paths :任何用户登陆时都会读取该文件,全局建议修改这个文件 。
  • /etc/profile:为系统的每个用户设置环境信息和启动程序,其配置对所有登录的用户都有效,一般不建议修改该文件。

用户级别

  • ~/.bash_profile:为当前用户设置专属的环境信息和启动程序,当用户登录时该文件执行一次。默认情况下,它用于设置环境变量,并执行当前用户的 .bashrc 文件,一般用户级环境变量会放到这个文件。
  • ~/.bash_login 和 ~/.profile:这三个文件也是依次执行的,如果 bash_profile 文件存在,则后面的两个文件就会被忽略不读了,如 bash_profile 文件不存在,才会以此类推读取后面的文件。

shell 打开时加载

  • /etc/bashrc 或 /etc/zshrc:系统级配置,为每个运行 bash/zhs shell 的用户执行该文件,当 bash/zhs shell 打开时,该文件被执行,其配置对所有使用 bash 的用户打开的每个 bash 都有效。
  • ~/.bashrc 或 ~/.zshrc:用户级配置,作用同上。它是 bash/zsh shell 打开的时候载入的,对当前用户打开的每个 bash 都有效。

如果系统默认 shell 使用的是 zsh 而不是 sh、bash,那么 zsh 是不加载 .bash_profile 文件的,而是加载 .zshrc。source .zshrc 在 zsh 环境下读取配置文件。

shell

上面多个地方提到了 shell,环境变量也是需要运行在 shell 上,那 shell 到底是什么呢?

shell 的概念

Shell 这个单词的原意是“外壳”,跟 kernel(内核)相对应,比喻内核外面的一层,即用户跟内核交互的对话界面。

具体来说,Shell 这个词有多种含义。

首先,Shell 是一个程序,提供一个与用户对话的环境。这个环境只有一个命令提示符,让用户从键盘输入命令,所以又称为命令行环境(command line interface,简写为 CLI)。Shell 接收到用户输入的命令,将命令送入操作系统执行,并将结果返回给用户。本书中,除非特别指明,Shell 指的就是命令行环境。

其次,Shell 是一个命令解释器,解释用户输入的命令。它支持变量、条件判断、循环操作等语法,所以用户可以用 Shell 命令写出各种小程序,又称为脚本(script)。这些脚本都通过 Shell 的解释执行,而不通过编译。

最后,Shell 是一个工具箱,提供了各种小工具,供用户方便地使用操作系统的功能。

以上这个 shell 概念来自阮一峰的 《Bash 脚本教程》

shell 的种类

不同的程序员写出的程序风格不同,有的喜欢这么写,有的喜欢那样写,所以就形成了不同的规范,就有了多种类型的 shell 了,就好像每个人喜欢穿不同的衣服一样。

历史上,主要的 Shell 有下面这些。

  • Bourne Shell(sh)
  • Bourne Again shell(bash)
  • C Shell(csh)
  • TENEX C Shell(tcsh)
  • Korn shell(ksh)
  • Z Shell(zsh)
  • Friendly Interactive Shell(fish)

随着时间的推移,每个 mac 系统会内置一些不同的 shell,那么如何查看你的 mac 安装了哪些 shell 呢?其实它的答案藏在了 /etc/shells 这个文件里:

1
2
3
4
5
6
7
8
9
10
cat /etc/shells

# 我的 mac 电脑内置的 shell
/bin/bash
/bin/csh
/bin/dash
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh

如何查看默认使用的是哪个 shell 呢?

1
2
3
4
5
6
7
# 当前系统默认的 shell
echo $SHELL
> /bin/zsh

# 当前进程正在使用的 shell
echo $0
> zsh

如果你想更改系统默认的 shell,你可以这么做:

1
2
# 以下将把 bash 设置为 默认 shell
chsh -s /bin/bash

配置环境变量

通过上面的介绍,你知道了你系统默认的 shell 是什么了。
我的是 zsh,那我就可以把我的环境变量保存在 ~/.zshrc 配置文件里。

1
2
3
4
5
# 同过 vim 打开 ~/.zshrc 文件
vim ~/.zshrc

# 配置 nginx 的环境变量 $PATH
export PATH=$PATH:/usr/local/nginx/sbin

通过 vim 编辑保存该文件后,想让环境变量立即生效还需要执行:

1
2
# 该命令的作用是读取并且执行该文件脚本
source ~/.zshrc

或者,可以把你的环境变量存在 ~/.bash_profile 里,然后在 ~/.zshrc 最后一行加上 source ~/.bash_profile,这样对于默认 shell 是 zsh 的用户来说,就可以让 ~/.bash_profile 里的配置生效了。

环境变量配置好后,就可以测试是否生效了。

1
2
# 如果没有报错,那就说明 nginx 的环境变量已经生效了
sudo nginx