变量是暂时存储数据的地方及数据标记,所存储的数据存在于内存空间中,通过正确地调用内存空间中变量的名字就可以取出与变量对应的数据。使用变量最大的好处就是使程序开发更为方便,同时,在编程中如不使用变量也很难完成相关程序开发工作。简单地说,变量就是用一个固定的字符串(字符、数字等组合)代替更多、更复杂的内容,该内容里可能还包含变量、路径、字符串等其他的内容。
默认情况下,在 bash Shell 中是不会区分变量类型;这和其他强类型语言(例如:Java/C 语言)是有区别的。当然也可以使用 declare 显示定义变量的类型,来指定 Shell 变量类型,但一般情况下没有这个需求。Shell 变量可分为两类:环境变量(全局变量)和普通变量(局部变量)。
一、环境变量
环境变量也可称为全局变量,可以在创建它们的 Shell 及其派生出来的任意子进程 Shell 中使用,环境变量又可分为自定义环境变量和bash 内置的环境变量。
环境变量一般是指用 export 内置命令导出的变量,用于定义 Shell 的运行环境,保证 Shell 命令的正确执行。Shell 通过环境变量来确定登陆用户名、命令路径、终端类型、登陆目录等,所有的环境变量都是系统全局变量,可用于所有子进程中,这包括编辑器、Shell 脚本和各类应用。环境变量可以在命令行中设置和创建,但用户退出命令行时这些变量值就会丢失,所以在用户家目录下的 .bash_profile 或 bashrc (非用户登录模式特有,例如远程SSH) 文件中,或者,在全局配置 /etc/profile 文件中定义或 /etc/bashrc (非用户登录模式特有,例如远程SSH) 。在将环境变量放入上述的文件中后,每次用户登录时这些变量都将被初始化,也就是可以永久保存环境变量不会随着用户退出命令行这些变量值就会丢失。
按照系统规范,所有环境变量的名字均采用大写形式。在将环境变量应用于用户进程程序之前,都应该用 export 命令导出定义,例如:
# .bash_profile # Get the aliases and functions if [ -f ~/.bashrc ]; then . ~/.bashrc fi # User specific environment and startup programs PATH=$PATH:$HOME/.local/bin:$HOME/bin export PATH JAVA_HOME=/home/redhat/jdk/jdk1.8.0_121 CLASSPATH=$JAVA_HOME/lib/ PATH=$JAVA_HOME/bin:$PATH export PATH JAVA_HOME CLASSPATH #zookeeper env export ZOOKEEPER_HOME=/home/redhat/zookeeper export PATH=$ZOOKEEPER_HOME/bin:$PATH
在查看设置的变量时,有3个命令可以显示变量的值:set、env 和 declare( 代替早期的 typeset )。set 命令输出所有的变量,包括全局变量和局部变量;env 命令只显示全局变量;declare 命令输出所有的变量、函数、整数和已导出的变量。set -o 命令显示 bash Shell 的所有参数配置信息。
[redhat@BING ~]$ env|tail
HOME=/home/redhat
LOGNAME=redhat
QTLIB=/usr/lib64/qt-3.3/lib
CLASSPATH=/home/redhat/jdk/jdk1.8.0_121/lib/
SSH_CONNECTION=10.11.63.25 52141 10.100.12.81 22
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/1000
DISPLAY=localhost:12.0
QT_PLUGIN_PATH=/usr/lib64/kde4/plugins:/usr/lib/kde4/plugins
_=/usr/bin/env
[redhat@BING ~]$ declare|tail
{
local quoted=${1//\'/\'\\\'\'};
printf "'%s'" "$quoted"
}
quote_readline ()
{
local quoted;
_quote_readline_by_ref "$1" ret;
printf %s "$ret"
}
[redhat@BING ~]$ set -o|head
allexport off
braceexpand on
emacs on
errexit off
errtrace off
functrace off
hashall on
histexpand on
history on
ignoreeof off
1.1 自定义环境变量
1.1.1 设置环境变量
设置环境变量的三种方法:
# export 命令和 declare 命令的格式如下: # 1、在设置变量时使用 export 命令 export 变量名=value # 2、再给变量赋值之后,再使用 export 命令 变量名=value; export 变量名 # 3、带 -x 选项的 declare 内置命令也可 (此处不要在变量名前面加$) declare -x 变量名=value
全局环境变量的配置:
# 常见的全局配置变量的配置文件 /etc/profile /etc/bashrc # 推荐在此文件中优先设置 # 若要在登录后初始化或显示加载内容,则把脚本文件放在 /etc/profile.d 下即可(无须加执行权限) /etc/profile.d
若要在登录后初始化或显示加载内容,则把脚本文件放在 /etc/profile.d 下即可(无须加执行权限),例如,设置登录提示:
1)第一种是在 /etc/motd 里增加提示字符串
[redhat@BING ~]$ cat /etc/motd
[redhat@BING ~]$ vim /etc/motd
[redhat@BING ~]$ sudo vim /etc/motd
[redhat@BING ~]$ cat /etc/motd
Welcome to BING Linux.
[redhat@BING ~]$
2) 第二种是在 /etc/profile.d/ 下面增加如下脚本
[redhat@SHOUFUAP ~]$ cat /etc/profile.d/welcome.sh # 展示welcome.sh脚本内容 Welcome to BING Linux.
1.1.2 显示或取消环境变量
1)通过 echo 或 printf 命令打印环境变量
[redhat@BING ~]$ echo $HOME /home/redhat [redhat@BING ~]$ echo $UID 1000 [redhat@BING ~]$ echo $PWD /home/redhat [redhat@BING ~]$ echo $SHELL /bin/bash [redhat@BING ~]$ echo $USER redhat [redhat@BING ~]$ printf "$HOME\n" /home/redhat [redhat@BING ~]$ # printf 是一个更复杂的格式化打印内容工具 # $HOME: 用户登录时进入的目录 # $UID: 当前用户的 UID (用户标识),相当于 id-u # $PWD: 当前工作目录的绝对路径名 # $SHELL: 当前 SHELL # $USER: 当前用户
在写 Shell 脚本时可以直接使用系统默认的环境变量,一般情况下时是不需要重新定义的,在使用定时任务等执行 Shell 脚本时建议在脚本中重新定义。
可以用 env 或 set 显示默认的环境变量;也可以用 unset 消除本地变量和环境变量。
1.1.3 环境变量初始化与对应文件的生效顺序
在登录Linux系统并启动一个bash shell时,默认情况下bash会在若干个文件中查找环境变量的设置。这些文件可统称为系统环境变量。bash检查的环境变量文件的情况取决于系统运行shell的方式。
系统运行shell的方式一般有三种:
1) 通过系统用户登录后默认运行的shell
2) 非登录交互式运行shell
3) 执行脚本运行非交互式shell
当用户登录Linux系统时,shell会作为登录shell启动。登录 Shell 读取环境变量文件的流程如下:
用户登录系统后首先会加载/etc/profile全局变量文件,这是Linux系统上默认的shell主环境变量文件。系统上每个用户登录都会加载这个文件。当加载完/etc/profile文件后,才会执行/etc/profile.d目录下的脚本文件。之后开始运行$HOME/.bash_profile(用户环境变量文件),在这个文件中,又会去找$HOME/.bashrc(用户环境变量文件),如果有则执行,如果没有则不执行。在$HOME/.bashrc文件中又会去找/etc/bashrc(全局环境变量文件),如果有则执行,如果没有则不执行。
如果用户的shell不是登录时启动的,非登录shell只会加载$HOME/.bashrc(用户环境变量文件),并会去找/etc/bashrc(全局环境变量文件)。如果希望在登录shell下也可以读到设置的环境变量等内容,就需要将变量设定等写入$HOME/.bashrc或者/etc/bashrc,而不是$HOME/.bash_profile或/etc/profile。