变量是暂时存储数据的地方及数据标记,所存储的数据存在于内存空间中,经过正确地调用内存空间中变量的名字就能够取出与变量对应的数据。使用变量最大的好处就是使程序开发更为方便,同时,在编程中如不使用变量也很难完成相关程序开发工做。简单地说,变量就是用一个固定的字符串(字符、数字等组合)代替更多、更复杂的内容,该内容里可能还包含变量、路径、字符串等其余的内容。linux
默认状况下,在 bash Shell 中是不会区分变量类型;这和其余强类型语言(例如:Java/C 语言)是有区别的。固然也可使用 declare 显示定义变量的类型,来指定 Shell 变量类型,但通常状况下没有这个需求。Shell 变量可分为两类:环境变量(全局变量)和普通变量(局部变量)。shell
环境变量也可称为全局变量,能够在建立它们的 Shell 及其派生出来的任意子进程 Shell 中使用,环境变量又可分为自定义环境变量和bash 内置的环境变量。编程
环境变量通常是指用 export 内置命令导出的变量,用于定义 Shell 的运行环境,保证 Shell 命令的正确执行。Shell 经过环境变量来肯定登录用户名、命令路径、终端类型、登录目录等,全部的环境变量都是系统全局变量,可用于全部子进程中,这包括编辑器、Shell 脚本和各种应用。环境变量能够在命令行中设置和建立,但用户退出命令行时这些变量值就会丢失,因此在用户家目录下的 .bash_profile 或 bashrc (非用户登陆模式特有,例如远程SSH) 文件中,或者,在全局配置 /etc/profile 文件中定义或 /etc/bashrc (非用户登陆模式特有,例如远程SSH) 。在将环境变量放入上述的文件中后,每次用户登陆时这些变量都将被初始化,也就是能够永久保存环境变量不会随着用户退出命令行这些变量值就会丢失。vim
按照系统规范,全部环境变量的名字均采用大写形式。在将环境变量应用于用户进程程序以前,都应该用 export 命令导出定义,例如:bash
# .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 的全部参数配置信息。less
[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
设置环境变量的三种方法:编辑器
# export 命令和 declare 命令的格式以下: # 一、在设置变量时使用 export 命令 export 变量名=value # 二、再给变量赋值以后,再使用 export 命令 变量名=value; export 变量名 # 三、带 -x 选项的 declare 内置命令也可 (此处不要在变量名前面加$) declare -x 变量名=value
全局环境变量的配置:函数
# 常见的全局配置变量的配置文件 /etc/profile /etc/bashrc # 推荐在此文件中优先设置 # 若要在登陆后初始化或显示加载内容,则把脚本文件放在 /etc/profile.d 下便可(无须加执行权限) /etc/profile.d
若要在登陆后初始化或显示加载内容,则把脚本文件放在 /etc/profile.d 下便可(无须加执行权限),例如,设置登陆提示:工具
1)第一种是在 /etc/motd 里增长提示字符串spa
[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)经过 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 消除本地变量和环境变量。
在登陆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。
本地变量(局部变量) 在用户当前 Shell 生存期的脚本中使用。变量名通常是由字母、数字、下划线组成的,能够以字母或下划线开头;变量的内容能够用单引号或双引号引发来,也可不加引号,但三者含义是不一样的。为普通变量的定义赋值,通常有如下三种写法:
# 赋值时不加引号 变量名=value # 赋值时加单引号 变量名='value' # 赋值时加双引号 变量名="value"
采用不一样的方式对普通变量进行定义的差别以下( $变量名表示输出变量,能够用 $变量名 和 ${变量名} ):
1) 定义 x 变量的方式是不加任何引号直接定义变量的内容,当内容为简单连续的数字、字符串、路径名时,能够这样用;其特色:不加引号时,值里有变量的会被解析后输出
# 定义变量 x=192.168.1.1-$x # 输出结果($x的值被解析) x=192.168.1.1-192.168.1.1
2) 定义 y 变量的方式是经过的的单引号定义,其特色:输出变量内容时单引号里是什么就输出什么,即便内容中有变量和命令(命令须要反引号`` 引发来)也会原样输出
# 定义变量 y='192.168.1.1-$x' # 输出结果($x的值不会被解析) y=192.168.1.1-$x
3) 定义 z 变量的方式是经过双引号定义变量,其特色:输出变量内容时引号里的变量及命令会通过解析后在输出内容,而不是把双引号中的变量名及命令(命令须要反引号`` 引发来)
# 定义变量 z=192.168.1.1-$x # 输出结果($x的值被解析) z=192.168.1.1-192.168.1.1-192.168.1.1
因此数字内容的变量定义能够不加引号,其余没有特别要求的字符串等定义最好都加上双引号,若是真的的须要原样输出就加单引号。同时,把一个命令的结果做为变量的内容赋值的方法在脚本开发中也是很经常使用的。
对须要获取命令结果的变量内容赋值的常见方法有两种:
# 把命令用反引号引发来(容易和单引号混淆) 变量名=`ls` # 把命令用 $() 括起来 变量名=$(ls) [redhat@BING jdk]$ ls jdk1.8.0_121 jdk-8u121-linux-x64.tar.gz [redhat@BING jdk]$ CMD=`ls` [redhat@BING jdk]$ echo $CMD jdk1.8.0_121 jdk-8u121-linux-x64.tar.gz [redhat@BING jdk]$ echo ${CMD} jdk1.8.0_121 jdk-8u121-linux-x64.tar.gz [redhat@BING jdk]$ CMD_PWD=$(pwd) [redhat@BING jdk]$ echo $CMD_PWD /home/redhat/jdk [redhat@BING jdk]$ echo ${CMD_PWD} /home/redhat/jdk [redhat@BING ~]$ echo H=$(date) H=Thu Oct 4 13:22:58 CST 2018 [redhat@BING ~]$ echo zcf etc_$(date +%F).tar.gz /etc # tar: 从成员名中删除开头的“/” ; tar: 从硬链接目标中删除开头的“/” zcf etc_2018-10-04.tar.gz /etc [redhat@BING ~]$ H=$(uname -n) [redhat@BING ~]$ echo ${H} BING [redhat@BING ~]$ echo zcf $H.tar.gz /etc/services # tar: 从成员名中删除开头的“/” zcf BING.tar.gz /etc/services [redhat@BING ~]$
echo 、sed 、grep 调用是符合上述结论的,可是当使用 awk 调用 Shell 中的变量时,会有一些特殊用法。就是无论变量如何定义、赋值,除了加单引号之外,利用 awk 直接获取变量的输出,结果都同样,所以,在 awk 取用 Shell 变量时,最好是先用 echo 加符号输出变量,而后经过管道给 awk ,进而控制变量的输出结果。