变量
shell编程是一个弱类型的编程语言: 弱类型编程的语言,变量一般不用声明变量的类型和长度,程序运行过程可以改变变量类型;程序的执行一般不需要程序有可执行程序,且程序的执行需要借助解释器,这种解释器是需要有执行权限的,将程序代码翻译一句执行一句,如python、php、shell等语言。 与之相对的是强类型的编程语言: 强类型的编程语言中的变量,一般需要声明其类型和长度,程序运行过程中不能改变变量的类型;程序开发需要开发环境,程序需要经过编译器编译成二进制可执行文件后,再执行,如go语言。
shell变量
shell中的变量,按照其生效的作用域可以分为如下几类变量:
- ==环境变量== export 声明的环境变量,对所有的shell、子shell都生效。 declare -x 变量名=value#将变量声明为环境变量。 ${!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(颜色和字体颜色序号相对应)