1、Shell的变量 变量可以分为两类:环境变量(全局变量)和普通变量(局部变量)
1.1、环境变量 使用 env|declare|set|export -p
等命令可以查看系统中的环境变量。
1 2 3 4 5 6 7 [lepeng@centos ~] XDG_SESSION_ID=1 HOSTNAME=clsn TERM=linux SHELL=/bin/bash HISTSIZE=1000 ...
输出一个系统中的 环境变量
1 2 [lepeng@centos ~] zh_CN.UTF-8
1.1.1、环境变量相关配置文件 1 2 3 4 5 /etc/proflie /etc/bashrc ~/.bashrc ~/.bash_profile /etc/proflie.d/
文件读取顺序(CentOS6和7都一样)
1 2 3 4 /etc/profile ~/.bash_profile ~/.bashrc /etc/bashrc
文件读取过程示意图
验证文件读取顺序的方法
1 2 3 4 5 6 7 8 sed -i '1a echo "$(date +%T-%s) /etc/profile1" >>/tmp/clsn' /etc/profile sed -i '$a echo "$(date +%T-%s) /etc/profile2" >>/tmp/clsn' /etc/profile sed -i '1a echo "$(date +%T-%s) /etc/bashrc1" >>/tmp/clsn' /etc/bashrc sed -i '$a echo "$(date +%T-%s) /etc/bashrc2" >>/tmp/clsn' /etc/bashrc sed -i '1a echo "$(date +%T-%s) ~/.bashrc1" >>/tmp/clsn' ~/.bashrc sed -i '$a echo "$(date +%T-%s) ~/.bashrc2" >>/tmp/clsn' ~/.bashrc sed -i '1a echo "$(date +%T-%s) ~/.bash_profile1" >>/tmp/clsn' ~/.bash_profile sed -i '$a echo "$(date +%T-%s) ~/.bash_profile2" >>/tmp/clsn' ~/.bash_profile
1.1.2、环境变量的一些注意点
变量名通常要大写。
变量可以在自身的Shell及子Shell中使用。
常用export
来定义环境变量。
env
默认可以显示所有的环境变量名称及对应的值。
输出时用“$变量名”,取消时用“unset变量名”。
书写cron定时任务时要注意,脚本要用到的环境变量最好先在所执行的Shell脚本中重新定义。
如果希望环境变量永久生效,则可以将其放在用户环境变量文件或全局环境变量文件里。
1.2、普通变量 本地变量在用户当前的Shell生存期的脚本中使用。例如,本地变量 a = 1
,这个值在当前 Shell 生存期中有意义。如果在 Shell 中启动另一个进程或退出,本地变量值将无效。例如:
1 2 3 4 5 6 7 8 9 10 [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] 1 [lepeng@centos ~] 2 [lepeng@centos ~] 3
小结:连续普通字符串内容赋值给变量,不管用什么引号或者不用引号,它的内容是什么,打印变量就输出什么
2 普通变量 2.0、变量名
变量名只能为字母、数字或下划线,只能以字母或下划线开头。
变量名的定义要有一定的规范,并且要见名知意。
示例:
1 2 3 LpAge =22 lp_age =22 lpSex =man
2.1、变量中引号的使用 只有在变量的值中有空格的时候,会使用引号。单引号与双引号的区别在于,是否能够解析特殊符号。
以单引号' '
包围变量的值时,单引号里面是什么就输出什么,即使内容中有变量和命令(命令需要反引起来)也会把它们原样输出。 这种方式比较适合定义显示纯字符串的情况,即不希望解析变量、命令等的场景。
以双引号" "
包围变量的值时,输出时会先解析里面的变量和命令,而不是把双引号中的变量名和命令原样输出。 这种方式比较适合字符串中附带有变量和命令并且想将其解析后再输出的变量定义。
反引号 ``是命令替换,命令替换是指 Shell 可以先执行``中的命令,将输出结果保存到变量。
建议:如果变量的内容是数字,那么可以不加引号;如果真的需要原样输出就加单引号;其他没有特别要求的字符串等最好都加上双引号,定义变量时加双引号是最常见的使用场景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~]
2.1.1、变量中引号的使用场景
内容是纯数字、简单的连续字符(内容中不带任何空格)时,定义时可以不加任何引号,例如:
没有特殊情况时,字符串一律用双引号定义赋值,特别是多个字符串中间有空格时,例如:
1 2 NFSD_MODULE="no load" MyName="Oldboy is a handsome boy."
当变量里的内容需要原样输出时,要用单引号,这样的需求极少,例如:
变量使用反引号赋值
1 2 3 4 5 6 [lepeng@centos ~] [lepeng@centos ~] 2017年 12月 05日 星期二 09:02:06 CST [lepeng@centos ~] [lepeng@centos ~] clsn_test.sh panduan.sh quanju.sh yhk.sh
2.2、定义变量的方式 三种定义变量的方式
直接赋值
传参(传递参数)
交互式设置变量,使用read命令
2.2.1、read命令说明 read命令的帮助说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Linux read 命令用于从标准输入读取数值。 read 内部命令被用来从标准输入读取单行数据。这个命令可以用来读取键盘输入,当使用重定向的时候,可以读取文件中的一行数据。 语法read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...] 参数说明: -a 后跟一个变量,该变量会被认为是个数组,然后给其赋值,默认是以空格为分割符。 -d 后面跟一个标志符,其实只有其后的第一个字符有用,作为结束的标志。 -p 后面跟提示信息,即在输入前打印提示信息。 -e 在输入的时候可以使用命令补全功能。 -n 后跟一个数字,定义输入文本的长度,很实用。 -r 屏蔽\,如果没有该选项,则\作为一个转义字符,有的话 \就是个正常的字符了。 -s 安静模式,在输入字符时不再屏幕上显示,例如login 时输入密码。 -t 后面跟秒数,定义输入字符的等待时间。 -u 后面跟fd ,从文件描述符中读入,该文件描述符可以是exec 新开启的。
在命令行中使用
1 2 3 4 5 6 7 8 9 10 [lepeng@centos ~] 132 [lepeng@centos ~] 132 [lepeng@centos ~] 456 [lepeng@centos ~] 456 [lepeng@centos ~] 132
在脚本中使用
1 2 3 4 5 6 7 8 9 [lepeng@centos ~]#!/bin/bash read -p '请输入:' aecho $a [lepeng@centos ~] 请输入:aaa aaa
2.2.2、定义方法实践 直接赋值方法
1 2 3 4 5 6 7 8 9 10 [lepeng@centos ~]#!/bin/bash ethFile=/etc/sysconfig/network-scripts/ifcfg-eth0echo $hobby ls $ethFile [lepeng@centos ~] bianliang.sh chanshu.sh clsn.sh clsn_test.sh panduan.sh quanju.sh xiugaizhuji.sh yhk.sh /etc/sysconfig/network-scripts/ifcfg-eth0
传参 (传递参数)
1 2 3 4 5 6 7 8 9 10 11 [lepeng@centos ~]# vim bianliang.sh #!/bin/bash # hobby=$1 ethFile=$2 echo $hobby ls $ethFile [lepeng@centos ~]# sh bianliang.sh basketball /etc/hostname basketball /etc/hostname
交互式设置变量 read
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [lepeng@centos ~]#!/bin/bash read -p "请输入你的银行卡号:" Yhkread -s -p "请输入密码:" miMaecho echo "你的银行卡号:" $Yhk echo "你的密码为:" $miMa [lepeng@centos ~] 请输入你的银行卡号:123456 请输入密码: 你的银行卡号: 123456 你的密码为: 123456
2.2.3、写一个交互脚本,实现能够定义主机名及IP地址 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 [lepeng@centos ~]#!/bin/bash ethFile=/etc/sysconfig/network-scripts/ifcfg-eth[01] Now_eth=`hostname -I|awk -F "[. ]+" '{print $4}' ` read -p "请输入主机名:" Hostnameread -p "请输入IP地址的主机位:" HostIP hostnamectl set -hostname $Hostname sed -i "s#${Now_eth} #${HostIP} #g" $ethFile read -p "是否重启服务器:{yes/no}" REboot if [ $REboot == yes ]then echo "系统将在10秒后重启!" shutdown -r 10 else echo "请稍后手动重启系统!" fi
脚本测试结果
1 2 3 4 5 6 7 8 9 10 [lepeng@centos ~] 请输入主机名:clsn 请输入IP地址的主机位:180 是否重启服务器:{yes/no}yes 系统将在10秒后重启! [lepeng@centos ~] 请输入主机名:clsn 请输入IP地址的主机位:180 是否重启服务器:{yes/no}no 请稍后手动重启!
2.3、变量引用 ${}
1 2 3 4 5 6 7 8 [lepeng@centos ~] [lepeng@centos ~] [lepeng@centos ~] 2017年 12月 05日 星期二 09:02:06 CST_day [lepeng@centos ~] 2017年 12月 05日 星期二 09:02:06 CST-day
3、特殊变量 3.1、位置变量 常用的特殊位置参数说明
位置变量
作用说明
$0
获取当前执行的shell脚本的文件名,如果执行脚本带路径那么就包括脚本路径。
$n
获取当前执行的shell脚本的第n个参数值,n=1..9
,当n为0时表示脚本的文件名,如果n大于9用大括号括起来{10},参数以空格隔开。
$#
获取当前执行的shell脚本后面接的参数的总个数。
$*
获取当前shell的所有传参的参数,不加引号同 $@
; 如果给 $*
加上双引号,例如:“$*”
,则表示将所有的参数视为单个字符串,相当于 “112$3”
。
$@
获取当前shell的所有传参的参数,不加引号同 $*
; 如果给 $@
加上双引号,例如:“$@”
,则表示将所有参数视为不同的独立字符串,相当于“$1” “$2” “$3”“……”
,这是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白。当“$*”
和“$@”
都加双引号时,两者有区别,都不加双引号时,两者无区别。
$#
,$*
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 [lepeng@centos ~]#!/bin/bash echo $0 echo "第一个参数:" $1 echo "第二个参数:" $2 echo "第10个参数:" ${10} echo "第11个参数:" ${11} echo "参数个数:" $# echo "参数:" $* [lepeng@centos ~] chanshu.sh 第一个参数: 1 第二个参数: 2 第10个参数: 10 第11个参数: 11 参数个数: 12 参数: 55 2 3 4 5 6 7 8 9 10 11 12
$*
与 $@
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [lepeng@centos ~] [lepeng@centos ~] I am [lepeng@centos ~] handsome [lepeng@centos ~] boy.. [lepeng@centos ~] I am handsome boy.. [lepeng@centos ~] I am handsome boy.. [lepeng@centos ~] I am handsome boy.. [lepeng@centos ~] I am handsome boy.. [lepeng@centos ~] I am handsome boy.. [lepeng@centos ~] I am handsome boy..
3.2、进程状态变量 Shell进程的特殊状态变量说明
位置变量
作用说明
$?
获取执行上一个指令的执行状态返回值(0为成功,非零为失败),这个变量最常用。
$$
获取当前执行的Shell脚本的进程号(PID),这个变量不常用,了解即可。
$!
获取上一个在后台工作的进程的进程号(PID),这个变量不常用,了解即可。
$_
获取在此之前执行的命令或脚本的最后一个参数,这个变量不常用,了解即可。
示例
1 2 3 4 5 6 7 8 [lepeng@centos ~] 0 [lepeng@centos ~] 1368 [lepeng@centos ~] [lepeng@centos ~]echo
4、变量子串 4.1、变量子串说明
表达式
说明
${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/pattem/string}
使用string代替第一个匹配的pattern
${parameter//pattem/string}
使用string代替所有匹配的pattern
计算变量的长度
1 2 3 4 5 [lepeng@centos ~] [lepeng@centos ~] 20 [lepeng@centos ~] 20
截取变量中的字符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 [lepeng@centos ~] [lepeng@centos ~] ABC123ABCabc [lepeng@centos ~] ABC123ABCabc [lepeng@centos ~] abcABC123ABC [lepeng@centos ~] abcABC123ABC [lepeng@centos ~] ABC123ABCabc [lepeng@centos ~] [lepeng@centos ~] abcABC123ABC [lepeng@centos ~] [lepeng@centos ~] 123ABCabc [lepeng@centos ~] 123ABCabc [lepeng@centos ~] abc [lepeng@centos ~] abcABC123ABC [lepeng@centos ~] abcABC123 [lepeng@centos ~] abc
替换变量内容
1 2 3 4 5 6 [lepeng@centos ~] abcABC123ABCabc [lepeng@centos ~] testABC123ABCabc [lepeng@centos ~] testABC123ABCtest
有关上述匹配删除的小结
#
表示从幵头删除匹配最短。
##
表示从开头删除匹配最长。
%
表示从结尾删除匹配最短。
%%
表示从结尾删除匹配最长。
a*c
表示匹配的突符串,*
表示匹配所有,a*c
匹配开头为a、中间为任意多个字符、结尾为c的字符串。
a*C
表示匹配的字符串,*
表示匹配所有,a*C
匹配开头为a、中间为任意多个字符、结尾为C的字符串。
有关替换的小结
一个“/”表示替换匹配的第-个字符串。
两个“/”表示替换匹配的所有字符串。
4.2、Shell的特殊扩展变量说明
表达式
说明
${parameter:-word}
如果parameter的变量值为空或未赋值,则会返回word字符串并替代变量的值用途.如果变量未定义,则返回备用的值,防止变量为空值或因未定义而导致异常
${parameter:=word}
如果parameter的变量值为空或未赋值,则设置这个变量值为word,并返回其值。位置变量和特殊变量不适用用途:基本同上一个 ${parameter:-word}
,但该变量又额外给parameter变量赋值了
${parameter:?word}
如果parameter变量值为空或未赋值,那么word字符串将被作为标准错误输出,否则输出变量的值。用途:用于捕捉由于变量未定义而导致的错误,并退出程序
${parameter:+word}
如果parameter变量值为空或未赋值,则什么都不做,否则word字符串将替代变量的值
特殊变量实践
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 [lepeng@centos ~]#!/bin/bash dir=echo ${dir:-/tmp} echo ${dir} echo ${dir:=/mnt} echo ${dir} dir2= (空格)echo ${dir2-/tmp} echo ${dir2} echo ${dir2:-/tmp} echo ${dir2} echo ${dir2=/mnt} echo ${dir2}
测试结果
1 2 3 4 5 6 7 8 [lepeng@centos ~] /tmp /mnt /mnt /tmp