<b>3.2 环境变量</b>
<b></b>
环境变量一般是指用export内置命令导出的变量,用于定义shell的运行环境,保证shell命令的正确执行。shell通过环境变量来确定登录用户名、命令路径、终端类型、登录目录等,所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器、shell脚本和各类应用。
环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,因此,如果希望永久保存环境变量,可在用户家目录下的.bash_prof?ile或.bashrc(非用户登录模式特有,例如远程ssh)文件中,或者全局配置/etc/bashrc(非用户登录模式特有,例如远程ssh)或/etc/prof?ile文件中定义。在将环境变量放入上述的文件中后,每次用户登录时这些变量都将被初始化。
按照系统规范,所有环境变量的名字均采用大写形式。在将环境变量应用于用户进程程序之前,都应该用export命令导出定义,例如:正确的环境变量定义方法为export oldgirl=1。
有一些环境变量,比如home、path、shell、uid、user等,在用户登录之前就已经被/bin/login程序设置好了。通常环境变量被定义并保存在用户家目录下的.bash_prof?ile文件或全局的配置文件/etc/prof?ile中,具体的环境变量说明参见表3-1。
表3-1 部分bash环境变量展示(执行env命令后获得)
变量名 含 义
_= 上一条命令的最后一个参数
bash=/bin/bash 调用bash实例时使用的全路径名
bash_versinfo=([0]="3"[1]="2"[2]="25" [3]="1"[4]="release"[5]="x86_64-redhat-linux-gnu") 使用2.0以上版本时,展开为版本信息
bash_version='3.2.25(1)-release' 当前bash实例的版本号
colors=/etc/dir_colors 颜色变量
columns=132 设置该变量,就给shell编辑模式和选择的命令定义了编辑窗口的宽度
dirstack=() 代表目录栈的当前内容
euid=0 在shell启动时被初始化的当前用户的有效id
groups=() 当前用户所属的组
histfile=/root/.bash_history 历史记录文件的全路径
histfilesize=50 历史文件能包含的最大行数
histsize=50 记录在命令行历史文件中的命令行数
home=/root 当前用户家目录
hostname=oldboy 当前主机名称
hosttype=x86_64 当前操作系统类型
ifs=$'\t\n' 内部字段分隔符,一般是空格符、制表符和换行符,用于划分由命令替换、循环结构中的表和所读取的输入产生的词的字段
inputrc=/etc/inputrc readline启动文件的文件名,取代默认的~/.inputrc
java_home=/application/jdk1.6.0_10 java home环境变量
lang=zh_cn.utf-8 字符集
logname=root 登录用户名称
machtype=x86_64-redhat-linux-gnu 包含一个描述正在运行bash的系统串
mailcheck=60 这个参数定义shell将隔多长时间(以秒为单位)检查一次由参数mailpath或mailfile指定的文件,看看是否有邮件到达。默认值为600s
mail=/var/spool/mail/root 邮件全路径
oldpwd=/root 前一个当前工作目录
optind=1 下一个由getopts内置命令处理的参数的序号
ostype=linux-gnu 自动设置成一个串,该串描述正在运行bash的操作系统,默认值由系统来决定
path=/usr/lib64/qt-3.3/bin:/usr/kerberos/sbin:
/usr/kerberos/bin
:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/bin:
/server/script/shangxian:/root/bin 全局path路径,命令搜索路径。一个由冒号分隔的目录列表,shell用它来搜索命令。默认路径由系统来决定,并且由安装bash的管理员来设置
pipestatus=([0]="0"[1]="0") 一个数组,包含一列最近在管道执行的前台作业的进程退出的状态值
ppid=1112 父进程的进程id
ps1='[\u@\h \w]\$ ' 主提示符串,默认值是$
ps2='>' 次提示符串,默认值是>
ps4=`+` 当开启追踪时使用的是调试提示符串,默认值是+,追踪可用set –x开启
pwd=/home 当前用户家目录
resin_home=/application/resin-3.1.6 这是通过export人为设置的环境变量,java环境会用
shell=/bin/bash 登录shell类型
shellopts=braceexpand:emacs:hashall:
histexpand:history:interactive-comments:monitor 包含一列开启的shell选项
shlvl=1 每启动一个bash实例就将其加1
term=vt100 终端设置
tmout=3600 退出前等待超时的秒数
uid=0 当前用户的uid,在shell启动时初始化
user=root 当前用户的用户名,在shell启动时初始化
在查看设置的变量时,有3个命令可以显示变量的值:set、env和declare(替代早期的typeset)。set命令输出所有的变量,包括全局变量和局部变量;env命令只显示全局变量;declare命令输出所有的变量、函数、整数和已经导出的变量。set -o命令显示bash shell的所有参数配置信息。
范例3-1:set、env和declare输出。
[root@oldboy ~]# env|tail
shlvl=1
home=/root
logname=root
cvs_rsh=ssh
moduleshome=/usr/share/modules
lessopen=||/usr/bin/lesspipe.sh %s
g_broken_filenames=1
bash_func_module()=() { eval `/usr/bin/modulecmd bash $*`
}
_=/bin/env
[root@oldboy ~]# declare|tail
_module_not_yet_loaded ()
{
comm -23 <(_module_avail|sort) <(tr : '\n' <<<${loadedmodules}|sort)
module ()
eval `/usr/bin/modulecmd bash $*`
[root@oldboy ~]# set|tail
[root@oldboy ~]# set -o|head
allexport off
braceexpand on
emacs on
errexit off
errtrace off
functrace off
hashall on
histexpand on
history on
ignoreeof off
3.2.1 自定义环境变量
1.?设置环境变量
如果想要设置环境变量,就要在给变量赋值之后或在设置变量时使用export命令,具体设置见下文的示例。其实,除了export命令,带-x选项的declare内置命令也可以完成同样的功能(注意:此处不要在变量名前面加$)。
export命令和declare命令的格式如下:
①export 变量名=value
②变量名=value ; export 变量名
③declare –x 变量名=value
提示: 以上为设置环境变量的3种方法。
范例3-2:定义环境变量并赋值的方法。
export name=oldboy
declare –x name=oldboy
name=oldboy ;export name
以下是自定义全局环境变量的示例:
[root@oldboy script]# cat /etc/profile|grep old
export oldboy='oldboy' #<==编辑/etc/profile,然后输出此行并保存
[root@oldboy script]# source /etc/profile #<==或. /etc/profile使其生效
[root@oldboy script]# echo $oldboy #<==在变量前加$符号并打印变量值
oldboy
[root@oldboy script]# env|grep oldboy #<==查看定义结果
oldboy=oldboy
下面来看看让环境变量永久生效的常用设置文件。
(1)用户的环境变量配置
配置如下:
[root@oldboy scripts]# ls /root/.bashrc #<==推荐在此文件中优先设置
/root/.bashrc
[root@oldboy scripts]# ls /root/.bash_profile
/root/.bash_profile
提示: 对于用户的环境变量设置,比较常见的是用户家目录下的.bashrc和.bash_profile。
(2)全局环境变量的配置
常见的全局环境变量的配置文件如下:
/etc/profile
/etc/bashrc #<==推荐在此文件中优先设置
/etc/profile.d/
若要在登录后初始化或显示加载内容,则把脚本文件放在/etc/prof?ile.d/下即可(无须加执行权限)。
2.?设置登录提示的两种方式
第一种是在/etc/motd里增加提示的字符串,如下:
[root@oldboy ~]# cat /etc/motd #<==文件里仅为字符串内容
welcome to oldboy linux shell training.
登录后显示内容如下:
last login : fri nov 7 15 :36 :56 2016 from 10.0.0.100
第二种是在/etc/prof?ile.d/下面增加如下脚本。
[root@oldboy ~]# cat /etc/profile.d/oldboy.sh #<==这里是脚本的内容
echo " here is oldboy training "
登录后显示的内容如下:
here is oldboy training
以下是在生产场景下(在java环境中),自定义环境变量的示例。
export java_home=/application/jdk
export classpath=$classpath:$java_home/lib:$java_home/jre/lib
export path=$java_home/bin:$java_home/jre/bin:$path:$home/bin
export resin_home=/application/resin
提示: 上述的环境变量设置通常放在/etc/profile全局环境变量里。
如果是写java的脚本,那么最好是把上述java环境配置放入脚本内重新定义,特别是作为定时任务执行的脚本。
3.2.2 显示与取消环境变量
1.?通过echo或printf命令打印环境变量
下面我们先来看看常见的系统环境变量。
$home:用户登录时进入的目录。
$uid:当前用户的uid(用户标识),相当于id?-u。
$pwd:当前工作目录的绝对路径名。
$shell:当前shell。
$user:当前用户。
......
范例3-3:通过echo和printf命令打印环境变量。
[oldboy@oldboy ~]$ echo $home
/home/oldboy
[oldboy@oldboy ~]$ echo $uid
504
[oldboy@oldboy ~]$ echo $pwd
[oldboy@oldboy ~]$ echo $shell
/bin/bash
[oldboy@oldboy ~]$ echo $user
[root@oldboy ~]# printf "$home\n"
#<==printf是一个更复杂的格式化打印内容的工具,一般不需要
/root
提示: 在写shell脚本时可以直接使用系统默认的环境变量,一般情况下是不需要重新定义的,在使用定时任务等执行shell脚本时建议在脚本中重新定义。
2.?用env或set显示默认的环境变量
用env(printenv)显示默认环境变量的示例如下:
[oldboy@oldboy ~]$ env
hostname=oldboy
shell=/bin/bash
histsize=1000
lc_all=c
mail=/var/spool/mail/oldboy
path=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/home/oldboy/bin
inputrc=/etc/inputrc
pwd=/home/oldboy
lang=zh_cn.gb18030
home=/home/oldboy
logname=oldboy
中间和结尾省略若干代码
用set也可以显示环境变量(包括局部变量),如下:
[root@oldboy ~]# set
apacheerr=hello
bash=/bin/bash
bash_aliases=()
bash_argc=()
bash_argv=()
bash_cmds=()
bash_lineno=()
bash_source=()
bash_versinfo=([0]="4" [1]="1" [2]="2" [3]="1" [4]="release" [5]="x86_64-redhat-linux-gnu")
bash_version='4.1.2(1)-release'
colors=/etc/dir_colors
columns=103
在3.2.1节还提到了一个相关的命令declare,大家还记得吗?
3.?用unset消除本地变量和环境变量
用unset消除本地变量和环境变量的示例如下:
[oldboy@oldboy ~]$ unset user
#<==此处为输出的空行
可以看到变量的内容显示为空。
环境变量的知识小结:
变量名通常要大写。
变量可以在自身的shell及子shell中使用。
常用export来定义环境变量。
执行env默认可以显示所有的环境变量名称及对应的值。
输出时用“$变量名”,取消时用“unset变量名”。
书写crond定时任务时要注意,脚本要用到的环境变量最好先在所执行的shell脚本中重新定义。
如果希望环境变量永久生效,则可以将其放在用户环境变量文件或全局环境变量文件里。
3.2.3 环境变量初始化与对应文件的生效顺序
在登录linux系统并启动一个bash shell时,默认情况下bash会在若干个文件中查找环境变量的设置。这些文件可统称为系统环境文件。bash检查的环境变量文件的情况取决于系统运行shell的方式。系统运行shell的方式一般有3种:
1) 通过系统用户登录后默认运行的shell。
2) 非登录交互式运行shell。
3) 执行脚本运行非交互式shell。
当用户登录linux系统时,shell会作为登录shell启动。此时的登录shell加载环境变量的顺序如图3-1所示。
用户登录系统后首先会加载/etc/profile全局环境变量文件,这是linux系统上默认的shell主环境变量文件。系统上每个用户登录都会加载这个文件。
当加载完/etc/profile文件后,才会执行/etc/profile.d目录下的脚本文件,这个目录下的脚本文件有很多,例如:系统的字符集设置(/etc/sysconfig/i18n)等,在后文开发跳板机案例里,我们也把脚本的起始加载放到这个目录下,以便用户登录后即刻运行脚本。
之后开始运行$home/.bash_profile(用户环境变量文件),在这个文件中,又会去找$home/.bashrc(用户环境变量文件),如果有,则执行,如果没有,则不执行。在$home/.bashrc文件中又会去找/etc/bashrc(全局环境变量文件),如果有,则执行,如果没有,则不执行。
如果用户的shell不是登录时启动的(比如手动敲下bash时启动或者其他不需要输入密码的登录及远程ssh连接情况 ),那么这种非登录shell只会加载$home/.bashrc(用户环境变量文件),并会去找/etc/bashrc(全局环境变量文件)。因此如果希望在非登录shell下也可读到设置的环境变量等内容,就需要将变量设定等写入$home/.bashrc或者/etc/bashrc,而不是$home/.bash_profile或/etc/profile。