本文档主要讲解Shell变量的核心基础知识与实践
shell
基本大纲:bash
1.Shell变量的分类
ssh
2.Shell中特殊且重要的变量ide
3.bash Shell 内置变量命令详解函数
4.Shell变量子串知识及实践this
5.Shell特殊扩展变量的知识与实践spa
一:变量可分为两类:环境变量(全局变量)和普通变量(局部变量)。orm
变量概念:简单地说、变量就是用一个固定的字符串(也多是字符,数字等的组合)代替更多、更复杂的内容,该内容里可能还会包含变量、路径、字符串等其余的内容。进程
1)环境变量:也可称为全局变量,能够在建立它们的Shell及其派生出来的任意子进程Shell中使用,环境变量又可分为自定义环境变量和bash内置的环境变量。(系统规范,全部的环境变量名字均采用大写形式)ip
1.设置环境变量,三种方法
①export 变量名=value
②变量名=value;export 变量名
③declare -x 变量名=value
2.用户的环境变量配置
/root/.bashrc
/root/.bash_profile
小结:对于用户的环境变量设置,比较常见的是用户家目录下的.bashrc和.bash_profile这两个文件
3. 全局环境变量的配置文件以下:
/etc/profile
/etc/bashrc
/etc/profile.d/
如果在登陆后初始化或显示加载内容,则把脚本文件放在/etc/profile.d/下便可(无须加执行权限)
4.定义环境变量的经验小结:
①变量名一般要大写
②经常使用export来定义环境变量
③用env和set显示默认的环境变量,用unset消除本地变量和环境变量。
④书写crond定时任务时要注意,脚本要用到的环境变量最好先在所执行的Shell脚本中从新定义。
⑤若是但愿环境变量永久生效,则能够将其放在用户环境变量文件或全局环境变量文件里。
2)普通变量:也可称为局部变量,只能在建立它们的Shell函数或Shell脚本中使用。普通变量通常由开发者在开发脚本程序时建立。
1.设置普通变量,三种方法
①变量名=value #此方法适合定义简单的数字,字符串,以及路径名
②变量名='value' #此方法适合定义显示纯字符串,不解析变量,以及命令的场景
③变量名="value" #此方法适合定义字符串中带有变量及命令,须要解析出来再输出的变量定义。定义变量加引号是最多见的使用场景
定义变量经验:
数字内容的变量定义能够不加引号,其余没有特殊要求的字符串等定义最好都加上双引号,若是真的须要原样输出就加单引号,定义变量加双引号是最多见的使用场景。
2.把一个命令的结果做为变量的内容赋值,两种方法
①变量名=`ls`
②变量名=$(ls) #推荐使用此法
生产场景中把命令的结果作为变量的内容进行赋值的方法在脚本开发时很常见
3.局部(普通)变量定义及赋值经验小结:
①若变量内容为连续的数字或字符串,赋值时,变量内容两边能够不加引号。例如:a=123,abc
②变量的内容不少时,若是有空格且但愿解析内容中的变量,就加双引号。例如a="abc $USER",此时输出变量会对内容中的$USER进行解析而后再输出
③但愿原样输出变量中的内容就用单引号引发内容进行赋值,例如:a='$USER' ,那么echo $a —> $USER
④命令的解析结果定义与赋值,要使用反引号将赋值的命令括起来,例如:a=`ls` ;或者用$()括起来,例如:a=$(ls)
⑤变量的输出方法:使用“$变量名”便可输出变量的内容,经常使用“echo $变量名”的方式,也能够用printf代替echo输出更复杂的格式内容
⑥用echo等命令输出变量的时候,也可用单引号、双引号、反引号,例如:echo $A 、echo '$A'、echo "$A",它们的用法和前面变量内容定义的总结是一致的。
⑦$dbname_tname,当变量后面链接有其余字符的时候,必须给变量名加上大括号{},例如:$dbname_tname改为${dbname}_tname
#注:这些结论仅针对Linux Shell,sed和grep是一致的,只是对于awk语言有些特别
awk结论:
awk加单引号后再同时加双引号能保证都是正确输出。无论变量如何定义,赋值,除了加单引号外,利用awk直接获取变量的输出,结果都是同样的。所以,在awk取用shell变量时,咱们更多地仍是喜欢先用echo加符号输出变量,而后经过管道给awk,进而控制变量的输出结果。例如:echo $USER|awk '{print $0}'
二:Shell中特殊且重要的变量
1)Shell中的特殊位置参数变量
$0 #获取当前执行的shell脚本的文件名,若是执行脚本包含了路径,那么就包含了路径,那么就包括脚本路径
$n #获取当前执行的Shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名;若是n大于9,则用大括号括起来,例如${10},接的参数一空格隔开
$# #获取当前执行的shell脚本后面接的参数的总个数
$* #获取当前shell脚本全部传参的参数,不加引号和$@相同;若是给$@加上双引号,例如:“$*”,则表示将全部的参数视为单个字符串,至关于“$1 $2 $3”
$@ #获取当前shell脚本全部传参的参数,不加引号和$*相同;若是给$@加上双引号,例如:“$@”,则表示将全部的参数视为不一样的独立字符串,至关于"$1""$2""$3""..."。这是将多参数传递给其它程序的最佳方式,由于它保留全部的内嵌在每一个参数里的任何空白。当"$@"和"$*"都加双引号时,二者是有区别的;都不加双引号时,二者无区别
2)Shell进程中的特殊状态变量
$? #获取执行上一个指令的执行状态返回值(0为成功,非零为失败),这个很经常使用
$$ #获取当前执行的Shell脚本的进程号(PID),这个变量不经常使用
$! #获取上一行在后台工做的进程的进程号(PID),这个变量不经常使用
$_ #获取在此以前执行的命令或脚本的最后一个参数,这个变量不经常使用
注:$?:不一样命令的执行结果中,$?的返回值不尽相同,但在工做场景中,经常使用的就是0和非0状态,0表示成功,非0表示运行失败或者未成功
三:bash Shell 内置变量命令详解
1.echo命令参数选项详解 :
-n #不换行输出内容 -e #解析转义字符(见下面的字符)
\n #换行 \r #回车 \t #制表符 \b #退格 \v #纵向制表符
#注:printf和echo -e的转义字符能力类似
2.eval
命令格式:eval args
功能:当shell程序执行到eval语句时,Shell读入参数agrs,并将它们组合成一个新的命令,而后执行
[root@localhost practice]# cat noeval.sh
echo \$$#
[root@localhost practice]# sh noeval.sh 2 1
$2
[root@localhost practice]# cat noeval.sh
eval "echo \$$#" #传入两个参数,$#为2,echo \$$#变为echo $2,再加上eval命令,使得$2从新解析输出,而不是自己。因此下面输出了2
[root@localhost practice]# sh noeval.sh 1 2
2
3.exec
命令格式:exec命令参数
功能:exec命令可以在不建立新的子进程的前提下,转去执行指定的命令,当指定的命令执行完毕后,该进程(也就是最初的Shell)就终止了,示例以下:
[root@localhost practice]# cat /tmp/tmp.log
1
2
[root@localhost practice]# cat exec.sh
exec < /tmp/tmp.log #读取log内容
while read line #利用read一行行读取处理
do
echo $line
done
echo OK
[root@localhost practice]# sh exec.sh
1
2
OK
4.read
命令格式:read变量名表
功能:从标准输入读取字符串等信息,传给shell程序内部定义的变量。
read -p "屏幕打印字符串:" a
echo $a #从屏幕打印输出赋值给脚本变量使用
5.shift
命令格式:shift-Shift positional parameters
功能:shift语句会按以下方式从新命名全部的位置参数变量,即$2成为$1,$3成为$2等,以此类推 做用:很方便
[root@localhost practice]# set -- "1" "2"
[root@localhost practice]# shift
[root@localhost practice]# echo $1
2
shift生产环境案例:
[root@localhost practice]# sed 8,25p /usr/bin/ssh-copy-id -n
ID_FILE="${HOME}/.ssh/id_rsa.pub"
if [ "-i" = "$1" ]; then
shift
# check if we have 2 parameters left, if so the first is the new ID file
if [ -n "$2" ]; then
if expr "$1" : ".*\.pub" > /dev/null ; then
ID_FILE="$1"
else
ID_FILE="$1.pub"
fi
shift # and this should leave $1 as the target name
fi
else
if [ x$SSH_AUTH_SOCK != x ] ; then
GET_ID="$GET_ID ssh-add -L"
fi
fi
6.exit
命令格式:exit-Exit the shell
功能:退出shell程序。在exit以后能够有选择地指定一个数位做为返回状态。
四:Shell变量子串知识及实践
1)变量子串介绍
①${parameter} #返回变量$parameter的内容
②${#parameter} #返回变量$parameter内容的长度(按字符),也适用于特殊变量
③${parameter:offset) #在变量${parameter}中,从位置offset以后开始提取子串到结尾
④${parameter:offset:length} #在变量${parameter}中,从位置offset以后开始提取长度为length的字串
⑤${parameter#word} #从变量${parameter}开头开始删除最短匹配的word子串
⑥${parameter##word} #从变量${parameter}开头开始删除最长匹配的word子串
⑦${parameter%word} #从变量${parameter}结尾开始删除最短匹配的word子串
⑧${parameter%%word} #从变量${parameter}结尾开始删除最长匹配的word子串
⑨${parameter/pattern/string} #使用string代替第一个匹配的pattern
⑩${parameter//pattern/string} #使用string代替全部匹配的pattern
2)变量子串实践
1).${parameter} #返回变量$parameter的内容
示例:
[root@aliyun dcindex]# ywxi="I am ywxi"
[root@aliyun dcindex]# echo ${ywxi}
I am ywxi
2).${#parameter} #返回变量$parameter内容的长度(按字符),也适用于特殊变量
示例:
[root@aliyun dcindex]# echo ${#ywxi}
9
[root@aliyun dcindex]# echo $ywxi|wc -L
9
[root@aliyun dcindex]# expr length "$ywxi"
9
[root@localhost ~]# echo $ywxi|awk '{print length'"$0"'}'
9
3).${parameter:offset) #在变量${parameter}中,从位置offset以后开始提取子串到结尾
示例:
[root@localhost practice]# echo ${ywxi}
I am ywxi
[root@localhost practice]# echo ${ywxi:2}
am ywxi
4).${parameter:offset:length} #在变量${parameter}中,从位置offset以后开始提取长度为length的字串
示例:
[root@localhost practice]# echo ${ywxi}
I am ywxi
[root@localhost practice]# echo ${ywxi:2:2}
am
等价于
[root@localhost practice]# echo ${ywxi}|cut -c 3-4
am
5).${parameter#word} #从变量${parameter}开头开始删除最短匹配的word子串
示例:
[root@localhost practice]# ywxi=abcABC123ABCabc
[root@localhost practice]# echo ${ywxi#a*C}
123ABCabc
[root@localhost practice]# echo ${ywxi#a*c}
ABC123ABCabc
6).${parameter##word} #从变量${parameter}开头开始删除最长匹配的word子串
示例:
[root@localhost practice]# echo $ywxi
abcABC123ABCabc
[root@localhost practice]# echo ${ywxi##a*c}
[root@localhost practice]# echo ${ywxi##a*C}
abc
7).${parameter%word} #从变量${parameter}结尾开始删除最短匹配的word子串
示例:
[root@localhost practice]# echo $ywxi
abcABC123ABCabc
[root@localhost practice]# echo ${ywxi%a*c}
abcABC123ABC
[root@localhost practice]# echo ${ywxi%a*C}
abcABC123ABCabc
8).${parameter%%word} #从变量${parameter}结尾开始删除最长匹配的word子串
示例:
[root@localhost practice]# echo $ywxi
abcABC123ABCabc
[root@localhost practice]# echo ${ywxi%%a*c}
[root@localhost practice]# echo ${ywxi%%a*C}
abcABC123ABCabc
有关匹配删除的小结:
#表示从开头删除匹配最短
##表示从开头删除匹配最长
%表示从结尾删除匹配最短
%%表示从结尾删除匹配最长
a*c表示匹配的字符串,*表示匹配全部,a*c匹配开头为a、中间为任意多个字符、结尾为c的字符串
a*C表示匹配的字符串,*表示匹配全部,a*c匹配开头为a、中间为任意多个字符、结尾为C的字符串
9).${parameter/pattern/string} #使用string代替第一个匹配的pattern
示例:
[root@localhost practice]# ywxi="I am oldboy,yes,oldboy"
[root@localhost practice]# echo $ywxi
I am oldboy,yes,oldboy
[root@localhost practice]# echo ${ywxi/oldboy/oldgirl}
I am oldgirl,yes,oldboy
10).${parameter//pattern/string} #使用string代替全部匹配的pattern
示例:
[root@localhost practice]# echo ${ywxi//oldboy/oldgirl}
I am oldgirl,yes,oldgirl
有关替换的小结:
#一个"/"表示替换匹配的第一个字符串
#两个"/"表示替换匹配的全部字符串
五:Shell特殊扩展变量的知识与实践
1)特殊扩展变量介绍
①${parameter:-word} #用途:若是变量未定义,则返回备用的值,防止变量为空值或因未定义而致使异常
②${parameter:=word} #用途:基本同上一个${parameter:-word},但该变量又额外给parameter变量赋值了
③${parameter:?word} #用途:用于捕捉因为变量未定义而致使的错误,并退出程序
④${parameter:+word} #若是parameter变量值为空或未赋值,则什么都不作,不然word字符串将替代变量的值
2)特殊扩展变量实践
shell范例11:
1)${parameter:-word} #用途:若是变量未定义,则返回备用的值,防止变量为空值或因未定义而致使异常
[root@localhost scripts]# echo $test
[root@localhost scripts]# result=${test:-UNSET}
[root@localhost scripts]# echo $result
UNSET
[root@localhost scripts]# echo $test
[root@localhost scripts]#
[root@localhost scripts]# test=oldboy
[root@localhost scripts]# echo $test
oldboy
[root@localhost scripts]# result=${test:-UNSET}
[root@localhost scripts]# echo $result
oldboy
[root@localhost scripts]# echo $test
oldboy
[root@localhost practice]# result=${test-UNSET}
[root@localhost practice]# echo $result
oldboy
2)${parameter:=word} #用途:基本同上一个${parameter:-word},但该变量又额外给parameter变量赋值了
[root@localhost practice]# result=${test:=UNSET}
[root@localhost practice]# echo $result
UNSET
[root@localhost practice]# echo $test
UNSET
[root@localhost practice]# result=${test=UNSET}
[root@localhost practice]# echo $result
UNSET
[root@localhost practice]# echo $test
UNSET
3)${parameter:?word} #用途:用于捕捉因为变量未定义而致使的错误,并退出程序
[root@localhost practice]# echo ${key:?not defined}
-bash: key: not defined
[root@localhost practice]# key=1
[root@localhost practice]# echo ${key:?not defined}
1
[root@localhost practice]# echo ${key?not defined}
1
[root@localhost practice]# unset key
[root@localhost practice]# echo ${key:?not defined}
-bash: key: not defined
4)${parameter:+word} #若是parameter变量值为空或未赋值,则什么都不作,不然word字符串将替代变量的值
[root@localhost practice]# unset oldboy
[root@localhost practice]# unset oldgirl
[root@localhost practice]# oldboy=${oldgirl:+word}
[root@localhost practice]# echo $oldboy
[root@localhost practice]# oldgirl=19
[root@localhost practice]# oldboy=${oldgirl:+word}
[root@localhost practice]# echo $oldboy
word
http启动服务示例:
[root@aliyun ~]# cat /etc/init.d/httpd
HTTPD_LANG=${HTTPD_LANG-"C"} #若是变量HTTPD_LANG未定义,则返回C,防止异常
httpd=${HTTPD-/usr/sbin/httpd} #若是HTTPD未定义,则返回/usr/sbin/httpd,防止异常
pidfile=${PIDFILE-/var/run/httpd/httpd.pid} #若是PIDFILE未定义,则返回/var/run/httpd/httpd.pid,防止异常
lockfile=${LOCKFILE-/var/lock/subsys/httpd} #若是LOCKFILE未定义,则返回/var/lock/subsys/httpd,防止异常