环境变量是什么?
环境变量(environment variables
)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。
环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如Windows和DOS操作系统中的path环境变量,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到path中指定的路径去找。用户通过设置环境变量,来更好的运行进程。
- shell的环境变量分为全局变量和局部变量。
- 全局变量对所有的shell会话及其子进程都有效,局部变量只在定义它们的进程中可见。
- 可以使用printenv查看全局变量,使用set查看全局变量和局部变量。
- 使用export可以将局部变量导出为全局变量。
- 使用unset可以删除一个已定义的环境变量。
- shell有许多默认的环境变量,但不是每一个变量都必须有一个值
环境变量PATH
的用法
echo $PATH
可以查看系统的环境变量PATH
的值
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
在Linux系统中PATH记录了 可执行文件的路径,这就是为什么我们执行系统命令的时候直接输入命令就行了(在系统任何地方),因为系统命令都是放在PATH变量记录的路径下,而自己写的脚本需要使用绝对路径。
我现在写了一个shell
脚本,当前目录是/tmp
,我要执行脚本:
1
bash test.sh
2
chmod +x test.sh && ./test.sh
想要在系统任何地方执行,把test.sh
脚本加上可执行权限,cp
到PATH
变量记录的路径里,如:/usr/local/bin
。然后在系统任何地方输入test.sh
就可以执行了
还有一种方法是把test.sh
脚本的绝对路径加入到PATH
变量中就行了
export PATH=$PATH:/tmp
这样我们可以直接运行/tmp/
下面的可执行文件,但这是临时的,也只对当前shell生效。
让PATH
永久生效的,需要把它加入到 /etc/profile
echo "export PATH=$PATH:/tmp">>/etc/profile source /etc/profile
把 export PATH=$PATH:/tmp
追加到/etc/profile
文件里,并不会使PATH生效,让其生效的是命令:source
也可以写做 .
(有些shell可能不支持)
它们的功能完全一样,只是两种不同写法。我们都应该见过这样一种写法,如:
for i in /etc/profile.d/*.sh; do if [ -r "$i" ]; then if [ "$PS1" ]; then . "$i" else . "$i" >/dev/null 2>&1 fi fi done
这里的”. $i
”实际上就是source $i
。这个命令的含义是:读取文件的内容,并在当前bash环境下将其内容当命令执行。注意,这与输入一个可执行脚本的路径的执行方式是不同的。路径执行的方式会打开一个子进程的bash环境去执行脚本中的内容,而source
方式将会直接在当前bash环境中执行其内容。所以这种方式主要用于想引用一个脚本中的内容用来改变当前bash环境。
如:加载环境变量配置脚本或从另一个脚本中引用其定义的函数时。
我们可以通过如下例子来理解一下这个内建命令的作用:
[root@centos]# cat source.sh #!/bin/bash aaa=1000 echo $aaa echo $$ [root@centos]# ./source.sh 1000 27051 [root@centos]# echo $aaa [root@centos]# . source.sh 1000 17790 [root@centos]# echo $aaa 1000 [root@centos]# echo $$ 17790
我们可以通过以上例子中的$aaa
变量看到当前bash环境的变化,可以通过$$
变量,看到不同执行过程的进程环境变化。
和环境变量有关的文件
/etc/profile
此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行. 并从/etc/profile.d
目录的配置文件中搜集shell的设置。 为每一个运行bash shell的用户执行此文件。当bash shell被打开时,该文件被读取。
/etc/bashrc
每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc
文件。
~/.bash_profile
是交互式、login 方式进入 bash 运行的~/.bashrc
是交互式 non-login 方式进入 bash 运行的通常二者设置大致相同,所以通常前者会调用后者。
~/.bashrc
该文件包含专用于你的bash shell的bash信息,当登录时以及每次打开新的shell时,该该文件被读取。
~/.bash_logout
当每次退出系统(退出bash shell)时,执行该文件。另外,/etc/profile
中设定的变量(全局)的可以作用于任何用户,而~/.bashrc
等中设定的变量(局部)只能继承/etc/profile
中的变量,他们是"父子"关系
执行顺序为:
/etc/profile -> ~/.bash_profile -> ~/.bashrc -> /etc/bashrc -> ~/.bash_logout
~/.bash_history
用户执行过的命令历史记录
/etc
下的是全局的对所有用户生效,而HOME
目录下的只对该用户生效,每个用户的家目录下都有这几个文件
如果万一误删了也没事儿,在/etc/skel/
下还有备用模板文件,cp
过去就行了
cp /etc/skel/* /home/test
我们目前已经知道有个PATH
变量,bash会在查找外部命令的时候到PATH
所记录的目录中进行查找,从这个例子我们可以先理解一下环境变量的作用。环境变量就类似PATH
这种变量,是bash预设好的一些可能会对其状态和行为产生影响的变量。bash中实现的环境变量个数大概几十个,所有的帮助说明都可以在man bash中找到。我们还是拿一些会在bash编程中经常用到的来讲解一下。
我们可以使用env
命令来查看当前bash已经定义的环境变量。set
命令不加任何参数可以查看当前bash环境中的所有变量,包括环境变量和私有的一般变量。一般变量的定义方法:
[root@centos ~]# aaa=1000 [root@centos ~]# echo $aaa 1000 [root@centos ~]# env|grep aaa [root@centos ~]# set|grep aaa aaa=1000
上面我们定义了一个变量名字叫做aaa
,我们能看到在set
命令中可以显示出这个变量,但是env
不显示。export
命令可以将一个一般变量变成环境变量。
[root@centos ~]# export aaa [root@centos ~]# env|grep aaa aaa=1000 [root@centos ~]# set|grep aaa aaa=1000
export
之后,env
和set
都能看到这个变量了。一般变量和环境变量的区别是:一般变量不能被子进程继承,而环境变量会被子进程继承。
[root@centos ~]# env|grep aaa aaa=1000 [root@centos ~]# bbb=2000 [root@centos ~]# echo $bbb 2000 [root@centos ~]# echo $aaa 1000 [root@centos ~]# env|grep bbb [root@centos ~]# bash [root@centos ~]# echo $aaa 1000 [root@centos ~]# echo $bbb [root@centos ~]#
上面测试中,我们的bash环境里有一个环境变量aaa=1000
,又定义了一个一般变量bbb=2000
。此时我们在用bash打开一个子进程,在子进程中我们发现,aaa
变量仍然能取到值,但是bbb
不可以。证明aaa
可以被子进程继承,bbb
不可以。
搞清楚了环境变量的基础知识之后,再来看一下bash中常用的环境变量:
变量 |
说明 |
CDPATH | 冒号分隔的目录列表,作为cd命令的搜索路径 |
HOME | 当前用户主目录 |
IFS | shell用来分隔文本字符串的一列字符 |
当前用户收件箱的文件名;shell会检查这个文件来查看有没有新邮件,我的系统上为/var/mail/allan | |
MAILPATH | 冒号分隔的当前用户收件箱的文件名列表;shell检查列表中的每个文件确认是否有新邮件 |
OPTARG | getopts命令处理的最后一个选项参数值 |
OPTIND | getopts命令处理的最后一个选项参数的索引号,默认值为1 |
PATH | 冒号分隔的shell查找命令的目录列表 |
PS1 | shell命令行界面的主提示符,推荐一个不错的提示符:PS1=${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\W\[\033[00m\]\$ |
PS2 | shell命令行界面的次提示符 |
PS3 | select命令的提示符 |
PS4 | 如果使用了bash的-x参数,在命令行显示之前显示的提示符 |
BASH | 运行当前shell实例的全路径名,我的系统值为/bin/bash |
BASH_ALIASES | 当前已设置别名的关联数组 |
BASH_ARGC | 含有传给子函数或shell脚本的参数总数的可变数组 |
BASH_ARGV | 含有传给子函数或shell脚本的参数的可变数组 |
BASH_CMDS | shell执行过的命令的所在位置的关联数组 |
BASH_COMMAND | shell正在执行的命令或者马上就执行的命令 |
BASH_ENV | 设置了的话,每个bash脚本会在运行前先尝试运行一下这个变量定义的启动文件 |
BASH_EXECUTION_STRING | 通过bash –c选项传递过来的命令 |
BASH_LINENO | 含有当前执行的shell函数的在源代码中行号的可变数组 |
BASH_REMATCH | 含有模式和它们通过正则表达式比较运算符=~匹配到的子模式的只读可变数组 |
BASH_SOURCE | 含有当前正在执行的shell函数的源码文件名的可变数组 |
BASH_SUBSHELL | 当前shell环境的嵌套级别,初始值是0 |
BASH_VERSION | 当前运行的bash shell的版本号 |
BASH_VERSINFO | 含有当前运行的bash shell的主版本号和次版本号的可变数组 |
BASH_XTRACEFD | 若设置成了有效的文件描述符(0,1,2),则‘set -x’调试选项声明的跟踪输出可被重定向;通常用来跟踪输出分出到一个文件中 |
BASHOPTS | 当前使能的bash shell选项列表 |
BASHPID | 当前bash进程的pid |
COLUMNS | 当前bash shell实例使用的终端的宽度 |
COMP_CWORD | 当前含光标位置的COMP_WORDS变量的索引值 |
COMP_LINE | 当前命令行 |
COMP_POINT | 当前光标位置相对于当前命令起始位置的索引 |
COMP_KEY | 用来调用shell函数补全功能的最后一个键值 |
COMP_TYPE | 代表尝试调用补全shell函数的补全类型的整数值 |
COMP_WORDBREAKS | Readline库里做单词补全的词分隔字符 |
COMP_WORDS | 含有当前命令行所有词的可变数组 |
COMPREPLY | 含有由shell函数生成的可能的填充字的可变数组 |
DIRSTACK | 含有目录栈当前内容的可变数组 |
EMACS | 设置为’t’是,表明emacs shell缓冲区正在工作而行编辑不能工作 |
EUID | 当前用户的有效用户ID |
FCEDIT | 供fc命令用的默认编辑器 |
FIGNORE | 冒号分隔的做文件名补全时要忽略的后缀名列表 |
FUNCNAME | 当前执行的shell函数的名称 |
GLOBIGNORE | 定义了文件名展开时忽略的文件名集合的冒号分隔的模式列表 |
GROUPS | 含有当前用户属组列表的可变数组 |
histchars | 控制历史记录展开的字符,最多可有三个字符 |
HISTCMD | 当前命令在历史记录中的位置 |
HISTCONTROL | 控制哪些命令留在历史记录列表中 |
HISTFILE | 保存shell历史记录列表的文件名,默认是.bash_history |
HISTFILESIZE | 最多在历史文件中存在多少行 |
HISTIGNORE | 冒号分隔的用来决定哪些命令不存仅历史文件的模式列表 |
HISTSIZE | 最多在历史文件中存多少条命令 |
HOSTFILE | shell在补全主机名时读取的文件 |
HOSTNAME | 当前主机的名称 |
HOSTTYPE | 当前运行bash shell的机器 |
IGNOREEOF | shell在退出前必须受到连续的EOF字符的数量。如果这个值不存在,默认是1 |
INPUTRC | readline初始化文件名,默认是.inputrc |
LANG | shell的语言环境分类 |
LC_ALL | 定义一个语言环境,覆盖LANG变量 |
LC_COLLATE | 设置对字符串排序时用的对照表顺序 |
LC_CTYPE | 决定着在文件名展开和模式匹配时用字符如何解释 |
LC_MESSAGES | 决定解释前置美元符的双引号字符串的语言环境设置 |
LC_NUMERIC | 决定着格式化数字时的语言环境设置 |
LINENO | 当前执行的脚步的行号 |
LINES | 定义了终端上可见的行数 |
MACHYPE | 用“cpu-公司-系统”格式定义的系统类型 |
MAILCHECK | shell查看邮件的频率,以秒为单位,默认 |
OLDPWD | shell之前的工作目录 |
OPTERR | 设置为1时,bash shell会显示getopts命令产生的错误 |
OSTYPE | 定义了shell运行的操作系统 |
PIPESTATUS | 含有前端进程的退出状态列表的可变数组 |
POSIXLY_CORRECT | 设置了的话,bash 会以POSIX模式启动 |
PPID | bash shell父进程的pid |
PROMPT_COMMAND | 设置了的话,在命令行主提示符显示之后会执行这条命令 |
PROMPT_DIRTRIM | 用来定义当启动了\w或\W提示符字符串转义时显示的尾部目录名数。删除的目录名会用一组英文句点替换 |
PWD | 当前工作目录 |
RANDOM | 返回一个0~32767的随机数;对其赋值可作为随机数生成器的种子 |
REPLY | read命令的默认变量 |
SECONDS | 自从shell启动到现在的秒数;对其赋值将会重新计数 |
SHELL | bash shell的全路径名 |
SHELLOPTS | 冒号分隔的打开的bash shell选项列表 |
SHLVL | shell的级别;每次启动一个新的bash shell,值增加1 |
TIMEFORMAT | 指定了shell显示时间值的格式 |
TMOUT | select和read命令在没有输入的情况下等待多久(以秒为单位)。默认值是0,表示无线长 |
TMPDIR | bash shell创建临时文件的目录名 |
UID | 当前用户的真实用户ID |
参考:
1.http://liwei.life/2016/06/13/shell%E7%BC%96%E7%A8%8B%E4%B9%8B%E5%86%85%E5%BB%BA%E5%91%BD%E4%BB%A4/
2.http://liwei.life/2016/05/30/shell%E7%BC%96%E7%A8%8B%E4%B9%8B%E6%89%A7%E8%A1%8C%E7%8E%AF%E5%A2%83/
3.http://www.time-track.cn/environment-variables-in-shell.html