环境变量
我们先通过实际操作来看看一些系统环境变量:
$ echo $SHELL
/bin/bash
$
$ echo $USER
linux-20
$
$ echo $HOME
/home/linux-20
$
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/go/bin:/usr/local/nodejs/bin:/home/linux-20/go/bin:/home/linux-20/.local/bin
$
$ printenv LANG
en_US.UTF-8
echo $VAR
可查看所有环境变量,printenv VAR
只可查看全局环境变量。
调用变量使用 $
加变量名,比如 $USER
、$PATH
,更规范的书写方式是 ${USER}
、${PATH}
。我们通过一个例子看看两者的区别:
$ echo $USER
linux-20
$
$ echo $USER_book
$ echo ${USER}_book
linux-20_book
$USER_book
这个变量是不存在的,我们需要将 _book
作为普通字串放到 $USER
后面组成新的字串,此时必须书写为 ${USER}_book
。
可以看到,加大括号的书写方式比较清晰,而且能够明确界定变量字串和普通字串。
全局环境变量/局部环境变量
环境变量有两种,「全局环境变量」和「局部环境变量」。全局变量对当前 shell 及子 shell 有效,局部变量仅对当前 shell 有效。
foo=bar
即定义了局部环境变量 foo
,它的值是 bar
。定义全局环境变量,foo=bar; export foo
(可以将多行命令写在一行,用分号隔开) 或者 export foo=bar
。请看下面的例子:
$ # 定义局部环境变量
$ foo=bar
$ echo $foo
bar
$ # 启动一个 bash 子进程,局部环境变量不会传递
$ bash
$ echo $foo
$ # 定义全局环境变量
$ export foo=bar
$ echo $foo
bar
$ # 再启动一个 bash 子进程,全局环境变量继续可用
$ bash
$ echo $foo
bar
$ # 退出 bash 子进程,回到初始 bash
$ exit
exit
$ exit
exit
env
或者 printenv
可输出所有全局环境变量,set
可输出所有环境变量 (输出结果会很长)。unset VAR
可删除环境变量。
profile
退出 bash 进程后,该进程运行时定义的环境变量也就不存在了。定义永久的环境变量则需要保存到相应的配置文件,此配置文件也称 profile。
profile 有系统级的和用户级的,系统级的 profile 是 /etc/profile
,用户级的 profile 通常是 ~/.profile
(~
表示当前用户的 home 目录)。
当启动交互式的登录 bash,首先加载系统 profile,然后加载用户 profile。用户 profile 是 ~/.bash_profile
~/.bash_login
~/.profile
这三个文件中的一个,按顺序读取,首先读取成功的有效。因此这三个文件有一个就可以,建议使用 ~/.profile
,除了 bash 它还被其他多种 shell 程序支持。
用户 profile 中有这样的脚本:if [ -f ~/.bashrc ]; then . ~/.bashrc; fi
,意思是如果 ~/.bashrc
文件存在,则执行它。这段脚本默认是有的,可别轻易删除了。
/etc/profile.d
/etc/profile
有如下配置:
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
这一段的作用是 /etc/profile.d
这个目录下所有以 .sh
结尾的文件都将作为系统 profile 加载。因此用户可以创建一个 /etc/profile.d/local.sh
文件,作为系统级的 profile 文件,这样管理会更加清晰。
$PATH
$PATH
是非常重要的一个变量,当我们敲一个命令,系统会在 $PATH
定义的路径下搜索可执行文件。
$PATH
的值像这样 /home/linux-20/bin:/usr/local/bin:/usr/bin:/bin
,多个路径用 :
隔开。执行命令时从左到右搜索,左边的优先级高。将用户的目录放前面,使得用户目录的程序比系统目录的程序优先执行。
我们使用的 ls
env
等命令,它们完整的路径是 /bin/ls
/usr/bin/env
,错误配置 $PATH
将带来严重的后果,请看下面的例子:
$ # 启动一个 bash 子进程
$ bash
$ echo $PATH
/home/linux-20/bin:/usr/local/bin:/usr/bin:/bin
$
$ # which 可以查看命令匹配到的可执行文件
$ which ls
/bin/ls
$ which env
/usr/bin/env
$ which which
/usr/bin/which
$
$ # 重新配置 PATH
$ export PATH="/usr/bin"
$ which ls
$ which env
/usr/bin/env
$ ls
bash: ls: command not found
$
$ # PATH 添加目录
$ export PATH=$PATH:/bin
$ echo $PATH
/usr/bin:/bin
$ which ls
/bin/ls
$
$ # 删除 PATH
$ unset PATH
$ which env
bash: which: No such file or directory
$
$ # 退出 bash 子进程
$ exit
exit
$ # 父进程不受影响
$ echo $PATH
/home/linux-20/bin:/usr/local/bin:/usr/bin:/bin
有些 Linux 程序提供二进制程序包,安装时只需下载并解压,然后配置 $PATH
即可。
比如安装 nodejs,通常的做法是将其二进制程序包解压到 /usr/local/nodejs
目录,然后在系统 profile 中加入一行 export PATH=/usr/local/nodejs/bin:$PATH
。要在 $PATH
中增加目录,推荐这样操作:export PATH=/newpath:$PATH
export PATH=$PATH:/newpath
。
何时加 $ 符号
调用环境变量时需要加 $
符号,配置环境变量时则不需要。export PATH=/newpath:$PATH
中,前面的 PATH 表示定义一个环境变量,后面的 $PATH
表示调用已有的环境变量。