shell脚本中的变量
所谓变量就是以一组文字或者字符串来存储一些变化数据,这在shell脚本的编写当中十分有用。
linux下的变量分为两种:
系统内置变量:
系统中比较常用的内置变量有:
HOME,SHELL,HISTSIZE,MAIL,PATH,LANG(LC_ALL)(设置语系),RANDOM(取得一个0~32767之间的随机数),PS1(设置用户的登录提示符),HOSTNAME,LOGNAME,USER
还有一些在脚本编写中经常用到的特殊变量
$0 正在被执行命令的名字。对于shell脚本而言,这是被激活命令的路径
$n 该变量与脚本被激活时所带的参数相对应。n是正整数,与参数位置相对应($1,$2…)
$# 提供脚本的参数号
$* 所有这些参数都被双引号引住。若一个脚本接收两个参数,$*等于$1$2
$@ 所有这些参数都分别被双引号引住。若一个脚本接收到两个参数,$@等价于$1$2
$? 前一个命令执行后的返回值
$$ 当前shell的进程号。对于shell脚本,这是其正在执行时的进程ID
$! 前一个后台命令的进程号
$_上条命令的执行结果
$-当前命令的引导符
为了区别与用户自定义变量的不同,系统变量通常使用大写。
用户自定义变量:
用户还可以自定义变量,如A=B,这里A是变量里面存储的值是B,等号两边不能有空格;
如果变量的值是一个包含空格等的字符串需要用""双引号或者''单引号引起来;
如果变量值中有特殊字符如$要用反斜杠\转义为普通字符($在shell中有特殊意义)。
如果变量的值是一个命令的执行结果可以这样来做A=$(uname -r)或者A=`uname -r`(这里为反引号)
变量名称只能为英文或者数字,但开头不能是数据,如定义一个变量为"2A"是错误的写法。
如果要取消变量的设置可以使用unset “变量名称”
双引号,单引号和反斜杠的用法:
单引号可以屏蔽任何特殊字符
双引号可以屏蔽$ 反斜杠\ 反引号`以外的任何特殊字符
\反斜杠屏蔽任何紧跟其后的单个特殊字符,等于在单个字符上加上单引号
不管是用户自定义变量还是系统内置变量重启系统后都不起作用了,当有用户登录时候login shell就会通过/etc/profile文件重新把系统变量声明一下。
shell相关的配置文件
1、/etc/profile这是全局的配置文件对所有用户都生效,login shell会取得这个文件,并且这个文件还会调用其他的文件,其中比较重要的是/etc/sysconfig/i18n
这个和语系设置相关的文件。
2、仅对某个用户生效,用户主目录下面的.bash_profile,.bash_login,.profile,login shell会试图依次找到这三个文件并读取其中的一个,如果.bash_profile文件存在就读取他,即使
其他两个文件存在也不读取,否则接着找第二个,.bash_profile还会读取.bashrc文件,这个文件主要设置了一些别名。
profile类:设置环境变量,运行用户登录时要执行的一些命令
bahsrc类:用来设置别名和本地变量
变量的查看和相关操作
1、使用echo “$变量名称”可以查看某个变量的值
2、env可以查看所有环境变量及相关说明
3、set可以查看所有shell变量的值(包括系统变量和自定义变量)
4、export不加参数可以显示所有环境变量的值,export “变量名称” 把某个变量设置为环境变量
5、declare可以用来声明变量的类型,一般变量默认类型是字符串的
-a 将变量声明为数组类型
-i 将变量声明为整数类型
-x 将变量设置为环境变量,同export +x将环境变量设置为自定义变量
-r 将变量设置为只读,不可修改,重新登录可以修改
环境变量在本shell和子shell中都有效,而局部变量(非环境变量)则只在本shell中有效
变量的键盘读取
read -p "Please enter your name:" -t 30 NAMED 这条命令会等待30秒将用户输入的字符串存入NAMED这个变量中
-p 后面可以跟提示语句,-t 后面接等待的时间
数组类型的变量
数组类型变量 var(index)=content
index就是一些数字代表1,2,...,数组变量一般用在循环或者判断交互的脚本中
#var[1]="small min"
#var[2]="big min"
#var[3]="nice min"
#echo ${var[1]},${[2]},${[3]}
#small min,big min,nice min
变量内容的修改
1、给变量增加内容:
使用“$变量名称”累加内容或者${变量名称}累加内容,如PATH="$PATH":/home/bin或者PATH=${PATH}:/home/bin
2、变量内容的删除:
#path=$PATH
#/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
#echo ${path#/*local/bin:}
#/usr/sbin:/usr/bin:/sbin:/bin 从前开始删除了前面的两个内容
# echo ${path#/*:}
#/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 从前开始找冒号,找到第一个冒号就删除冒号之前的内容
#echo ${path##/*:}
#/bin 从前开始找到所有的冒号,删除冒号之前的内容就剩下最后一个目录
这里的目录都是以冒号分割的,要删除目录就是删除/到:之间的内容,所谓#就是从前开始找最短匹配,##就是从前开始找最长匹配,
类似的还有%和%%分别是从后开始查找找最短和最长匹配
#echo ${path%:*bin}
#/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin 最后一个目录被删除了
#echo ${path%%:*bin}
#/usr/local/sbin 后面所有的目录都被删除了,只保留了第一个
关键是找到特征符然后确定从后或者是从前删除
3、变量的测试与内容替换:
1.测试变量是否存在不存在则赋值
#echo $username
为空
#username=$(username-root)
#echo $username
#root
2.若变量未设置或为空字符串则为变量赋值
#username=""
#username=${username-root}
#echo $username
为空,因为username被设置为空字符串了,所以值赋不上
#username=${username:-root}
#echo $username
#root 对于未设置或是空字符串的变量可以使用:-来赋值