1. Shell环境变量介绍

  • shell的环境变量分为全局变量和局部变量。
  • 全局变量对所有的shell会话及其子进程都有效,局部变量只在定义它们的进程中可见。
  • 可以使用printenv查看全局变量,使用set查看全局变量和局部变量。
  • 使用export可以将局部变量导出为全局变量。
  • 使用unset可以删除一个已定义的环境变量。
  • shell有许多默认的环境变量,但不是每一个变量都必须有一个值

2. 默认的shell环境变量

注:下面说明中提到的环境变量的默认值都是我在我的系统(Ubuntu 14.04 x86_64)上面测的,不一定在所有的Linux发行版上面都一样

变量

说明

CDPATH 冒号分隔的目录列表,作为cd命令的搜索路径
HOME 当前用户主目录
IFS shell用来分隔文本字符串的一列字符
MAIL 当前用户收件箱的文件名;shell会检查这个文件来查看有没有新邮件,我的系统上为/var/mail/allan
MAILPATH 冒号分隔的当前用户收件箱的文件名列表;shell检查列表中的每个文件确认是否有新邮件
OPTARG getopts命令处理的最后一个选项参数值
OPTIND getopts命令处理的最后一个选项参数的索引号,默认值为1
PATH 冒号分隔的shell查找命令的目录列表
PS1 shell命令行界面的主提示符,推荐一个不错的提示符:PS1=${debian_chroot:+($debian_chroot)}[33[01;32m]u@h[33[00m]:[33[01;34m]W[33[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

可以看到,bash shell有许多的内置环境变量,而且不是所有的默认环境变量都会在运行set命令时列出。我们只要记住一些常用的比较重要的就可以了。

3. 启动bash shell的三种方式

当我们登录Linux系统启动一个bash shell时,默认情况下bash在几个文件中查找命令,这些文件称作启动文件。bash 检查的启动文件取决于启动bash shell的方式。而启动bash shell有三种方式:

(1)登录时当做默认登录shell。当我们登录Linux系统时,bash shell会作为登录shell启动。登录shell会从四个不同的启动文件中读取命令。下面是bash shell处理这些文件的次序:

  • /etc/profile
  • $HOME/.bash_profile
  • $HOME/.bash_login
  • $HOME/.profile

(2)作为非登录shell的交互式shell。比如我们敲入bash命令启动一个shell,这样启动的交互式shell不会去访问/etc/profile文件,而会去用户的HOME目录下检查.bashrc文件是否存在。

(3)非交互式shell。比如系统执行脚本时用的就是这种shell。当shell启动一个非交互式的shell进程时,它会检查BASH_ENV这个环境变量,如果这个环境变量有设置,shell会执行文件里面的命令。

4. 可变数组

之前介绍的很多环境变量都使用了可变数组,从名字可以看出就是一个长度可变的数组。要把某个环境变量设置成可变数组(即设置多个值),可以把值房子括号里,值与值之间用空格分隔:

allan@ubuntu:~$ mytest=(one two three four five)

不能通过echo数组名来查看整个数组(那样只会显示第一个元素),而必须要用代表它在数组中位置的数值索引值来访问(索引值从0开始),数值用方括号括起来;可用通配符显示整个数组:

allan@ubuntu:~$ echo ${mytest[2]}
three
allan@ubuntu:~$ echo ${mytest[*]}
one two three four five

可以用unset来删除数组中的某个值或整个数组:

allan@ubuntu:~$ unset mytest[2]
allan@ubuntu:~$ echo ${mytest[*]}
one two four five
allan@ubuntu:~$ echo ${mytest[2]}

allan@ubuntu:~$ echo ${mytest[3]}
four
allan@ubuntu:~$ mytest[2]=seven
allan@ubuntu:~$ echo ${mytest[*]}
one two seven four five