变量
shell编程是一个弱类型的编程语言:
弱类型编程的语言,变量一般不用声明变量的类型和长度,程序运行过程可以改变变量类型;程序的执行一般不需要程序有可执行程序,且程序的执行需要借助解释器,这种解释器是需要有执行权限的,将程序代码翻译一句执行一句,如python、php、shell等语言。
与之相对的是强类型的编程语言:
强类型的编程语言中的变量,一般需要声明其类型和长度,程序运行过程中不能改变变量的类型;程序开发需要开发环境,程序需要经过编译器编译成二进制可执行文件后,再执行,如go语言。
shell变量
shell中的变量,按照其生效的作用域可以分为如下几类变量:
- 环境变量
export 声明的环境变量,对所有的shell、子shell都生效。
declare -x 变量名=value#将变量声明为环境变量。
! v a r : 获 取 v a r 变 量 最 底 层 的 值 ( 如 a = b ; b = 1 那 么 {!var}:获取var变量最底层的值(如a=b;b=1那么 !var:获取var变量最底层的值(如a=b;b=1那么a的值为b,${!a}的值为1) - 本地变量
local VARNAME=VALUE声明的环境变量,只在函数内生效。 - 位置变量
$0:所有参数
$1:第一个参数
$2:第二个参数
$@:所有参数
$*:所有参数 - 特殊变量
$?:返回命令执行的状态码
其中:0表示执行成功,127表示命令未找到
变量(环境变量,本地变量都可以使用)的撤销:unset VARNAME
查看环境变量:printenv、env、export
变量补充新值:PATH=$PATH:VALUE
整数型变量声明: declare -i 变量名=value
注意:变量不进行算数运算,所有的变量值都当字符串做处理。
shell程序
命令的堆砌,按照实际需求,结合命令流程控制语句实现的源程序。
整数运算和小数运算
- $()运算:sum=$(($a+$b))
- $[]运算:sum=$[$a+$b]
- let命令:let sum=$a+$b
- expr命令:expr sum=$a + $b
常用于变量值类型判断,若不是整数,则返回非0的状态码。
#判断变量值是否为整数的例子:
#非整数相加报错
~]# expr 1 + 1.1
expr: non-integer argument
#查看状态值为2
[root@lg ~]# echo $?
2
#整数和字符串相加报错
[root@lg ~]# expr 1 + var
expr: non-integer argument
#查看状态值为2
[root@lg ~]# echo $?
2
#若整数运算则能正常执行
~]# expr 1 + 1
2
[root@lg ~]# echo $?
0
- bc命令:sum=$(echo “$a+$b”|bc)
bc可以进行整数和浮点数运算,也可以进行进制转换。
#整数运算:+、-、*、/、%、^
~]# bc <<< 1+1
2
~]# echo "1+1"|bc
2
#小数运算:scale=N;声明保留小数点N位,需注意bc在进行除法运算时才会保留小数点后N位
~]# echo "scale=2;3/2"|bc
1.50
#进制转换:ibase=M表示转换前数字是M进制,obase=M表示转换后数字是M进制
~]# echo "ibase=10;obase=2;128"|bc
10000000
条件测试
方式一:test 表达式
方式二:[ 表达式 ]
数值测试
- eq:是否等于
- lt:是否小于
- gt:是否大于
- le:是否小于等于
- ge:是否大于等于
- ne:是否不等于
文件测试
- e:文件是否存在
- d:文件是否为目录
- f:文件是否为普通文件
字符串测试
- “strings1” = “strings2”:strings1是否和strings2相同
- “strings1” != “strings2”:是否不同
- z strings:测试指定字符串长度是否为0。注意:空格有长度。
- [[ “$var” =~ “strgins” ]]:测试var变量的值是否包含strings。
逻辑运算符
- && 逻辑与
- || 逻辑或
布尔运算符
- a:且
- o:或
- !:非
条件测试语句
- 单分支if语句
if [ 条件表达式 ];then
语句
fi - 双分支if语句
if [ 条件表达式1 ];then
语句1
else
语句2
fi - 多分支if语句
if [ 条件表达式1 ];then
语句1
elif [ 条件表达式2 ];then
语句2
else
语句3
fi
条件测试实例
表达式是命令执行结果,命令执行成功,条件就成立;也可以在命令前面加!表示命令执行失败,条件成立。
if command ;then
fi
循环
- for循环1
for 变量 in 列表
do
循环体
done - for循环2
for ((初始变量;退出条件;运算))
do
循环体
done
#eg1:求1到100的和。
#法一(脚本内容如下):
#!/bin/bash
declare -i sum=0
for digit in $(seq 1 100)
do
sum=$(($digit+$sum))
done
echo $sum
#法二:
~]# declare -i sum=0;for ((i=:1;i<=100;i++));do let sum=sum+i;done;echo $sum
5050
#eg2:向系统上的所有用户问好。
#!/bin/bash
fileName=/etc/passwd
for user in $(cut -d":" -f1 $fileName)
do
echo "hello, $user!"
done
#eg3:向系统上的所有用户问好,并显示他们的shell。
#!/bin/bash
fileName=/etc/passwd
for user in $(cut -d":" -f1,7 $fileName)
do
echo "$user"| sed -rn 's#(.*[^/]):(/.*)#Hello, \1! Your shell is \2.#p'
done
- while循环1:常用于循环次数不确定的循环。
while [ 条件表达式 ]
do
循环体
done - while循环2:借助read命令,以行为一个变量值进行循环,类似于IFS=$’\n’(无空格)
while read -r 变量名
do
循环体
done <FILE - until循环:和while相反,until表示条件成立退出循环。
until [ 条件表达式 ]
do
循环体
done
#!/bin/bash
LINEFILE=./anaconda-ks.cfg
declare -i sum=0
while read -r LINE
do
echo "$sum,$LINE"
let sum++
done < $LINEFILE
#
#
IFS=$'\n'
for LINE in $(cat $LINEFILE);do
echo "$sum: $LINE"
done
循环控制语句
- continue:不执行continue下面的内容,进行下一次循环。
- break:跳出循环。
case语句
case $变量 in
value1)
语句1
;;
value2)
语句2
;;
value3 | value4)
语句3
;;
*)
语句5
esac
数组array
shell只支持一维数组,不支持多维数组。
- 数组的定义:
数组的元素用空格隔开,数组第一个元素的索引为0.
array_name=(value1 value2 value3…) - 数组的引用:
${array_name[n]} - 获取所有元素:
${array_name[*]} - 获取所有元素:
${array_name[@]} - 获取数组的长度:
${#array_name[@]} - 获取单个元素的长度:
${#array_name[n]} - 向数组中追加元素
array_name[${#array_name[@]}]=value4
map
- 声明map(使用前需要声明)
declare -A MapName - 初始化map
MapName=([“1”]=“1” [“2”]=“2”)
MapName[“3”]=“3” - 输出所有key
echo ${!MapName[@]} - 输出所有value
echo ${MapName[@]} - 输出map的长度
echo ${#MapName[@]} - 通过key访问value
echo ${MapName[“1”]} - 遍历key
for key in ${!MapName[@]}
do
echo $key
done - 遍历value
for value in ${MapName[@]}
do
echo $value
done
函数function
- 定义函数1
[ function ] funName () {
函数体
} - 函数调用
funName - 定义函数2
[ function ] funName () {
函数体
return $1 $2
}
函数执行的状态结果
$?:获取函数的执行结果;
return定义函数执行状态结果值,0-255
有return的地方意味着函数执行结束。
函数的执行结果
`functionName`
可以使用``或$()来获取函数的执行结果
函数传参
functionName var1 var2
向functionName传递var1 和 var2
函数参与循环
- 引用其他脚本
- . /path/to/file.sh
- source /path/to/file.sh
常用技巧之颜色输出
如何将echo出的内容颜色化显示:
显示颜色格式:
\033[NUMm strings \033[0m
\033:开启颜色控制
[NUMm:NUM是数字控制,不同的数字表示不同的控制方法,包括字体、颜色、字体背景色控制方法
strings:表示被设定该颜色的字符串
\033[0m:表示颜色控制结束
控制方法:多个控制方法用分号隔开
1.字体:1-7(1:加粗,3:斜体,4:下划线,5:闪烁,7,颜色反转)
eg:~]# echo -e '\033[7;5m1\033[0m' 1 #闪烁和颜色反转
2.字体颜色:31-37(31:红色,32:绿色,33:黄色,34:蓝色,35:紫色,37:白色)
3.字体背景:41-47(颜色和字体颜色序号相对应)