一:分支语句
==结束语句等于开始语句得单词反着写==
1.1 if语句
if 表达式 then
逻辑处理
elif 表达式 then
逻辑处理
else
逻辑处理
fi
1.1.1 单支语句
1.1.2 双分支语句
1.1.3 多分支语句
1.2 case条件结构语句
1.2.1 case语法结构
case 表达式 in
值)
;;
esac
1.2.2 case与if的对比
case书写方式
case $name in
值1)
指令1
;;
值2)
指令2
;;
*)
指令
esac
1.2.2 case与if的对比
case书写方式
case $name in
值1)
指令1
;;
值2)
指令2
;;
*)
指令
esac
if书写方式
if [ $name == "值1" ]
then
指令1elif [ $name == "值2" ]
then
指令2
else
指令
fi
1.2.3 case值的书写方式
apple)
echo -e "$RED_COLOR apple $RES"
;;
可以这样写,输入2种格式找同一个选项
apple|APPLE)
echo -e "$RED_COLOR apple $RES"
;;
*)
echo -e "$RED_COLOR apple $RES"
;;
二:循环语句
2.1 for循环
2.1.1 列表for循环(常用)
#!/bin/bash
for i in 取值列表 do
循环主体/命令
done
2.1.2 类似C语言的风格
for((exp1;exp2;exp3))
do
指令...done
编写类似C语言风格脚本
Shell中的两种样式
2.2 while语法
while:当...时候,满足条件执行
基本结构:
while 条件
do
命令
done
2.3 until循环
until:直到...时候,不满足条件执行
基本结构
until condition
do
do something...
done
2.4 跳出循环
shell中也支持break跳出循环, continue跳出本次循环.用法与C, Java中相同
三、函数
Shell 函数的本质是一段可以重复使用的脚本代码,这段代码被提前编写好了,放在了指定的位置,使用时直接调取即可。
Shell 中的函数和C++、Java、Python、C# 等其它编程语言中的函数类似,只是在语法细节有所差别。
3.1 基本语法
function name() {
statements
[return value]
}
对各个部分的说明:
-
function
是 Shell 中的关键字,专门用来定义函数; -
name
是函数名; -
statements
是函数要执行的代码,也就是一组语句; -
return value
表示函数的返回值,其中 return 是 Shell 关键字,专门用在函数中返回一个值;这一部分可以写也可以不写。 -
由包围的部分称为函数体,调用一个函数,实际上就是执行函数体中的代码。
3.2 函数定义的简化写法
如果嫌麻烦,函数定义时也可以不写 function 关键字:
name() {
statements
[return value]
}
如果写了 function 关键字,也可以省略函数名后面的小括号:
function name {
statements
[return value]
}
建议使用标准的写法,这样能够做到“见名知意”,一看就懂。
3.3 函数调用
调用 Shell 函数时可以给它传递参数,也可以不传递。如果不传递参数,直接给出函数名字即可:
name
如果传递参数,那么多个参数之间以空格分隔:
name param1 param2 param3
不管是哪种形式,函数名字后面都不需要带括号。
示例一:
定义一个函数
#!/bin/bash
add(){
echo '加法计算'
}
add
可以将调用放在定义的前面,也就是写成下面的形式:
#!/bin/bash
add
add(){
echo '加法计算'
}
示例三
#!/bin/bash
dev(){
echo '减法计算'
a=$1
b=$2
echo ${a}-${b}=$((a-b))
}
dev 4 2
示例三
使用 $@ 来遍历函数参数,定义一个函数,计算所有参数的和:
#!/bin/bash
getsum(){
local sum=0
for n in $@
do
((sum+=n))
done
return $sum
}
#调用函数并传递参数
getsum 10 20 30 40 50
echo $?
四、状态码
Shell 中运行的命令会使用0-255之间的整数值,作为退出状态码,并以此来告知shell该命令执行的状态。通常情况下,约定0代表命令成功结束,非0代表程序非正常退出
典型退出状态码及其含义 | |
---|---|
退出状态码 | 含义 |
0 | 命令运行成功 |
1 | 通知未知错误 |
2 | 误用shell命令 |
126 | 命令不可执行 |
127 | 没有找到命令 |
128 | 无效退出参数 |
128+x | linux信号x的严重错误 |
130 | 命令通过Ctrl+C终止 |
255 | 退出状态码越界 |
-
$?:返回上一条语句或脚本执行的状态
-
0:成功
-
1-255:不成功
-
exit 命令,用于退出脚本或当前Shell
exit 命令n 是一个从 0 到 255 的整数 ,0 表示成功退出,非零表示遇到某种失败 ,返回值被保存在状态变量 $? 中
exit n
4.1 示例
示例一:
未指定函数返回值,且函数最后一条命令执行成功
#!/bin/bash
hello(){
echo "Hello World"
# cho "Hello World"
}
hello
echo '命令执行结果:'$?
#!/bin/bash
hello(){
# echo "Hello World"
cho "Hello World"
}
hello
echo '命令执行结果:'$?
说明:由于此时未指定返回值,所以以函数最后一条被执行的命令echo "Hello World";的执行状态作为函数的退出状态。此时 echo "Hello World";执行成功,所以返回0作为退出状态码。
示例二
指定函数返回值,|外
#!/bin/bash
hello(){
echo "Hello World"
# 函数返回值在约定范围内
return 3
# 函数返回值在约定范围外
# return 333
}
hello
echo '命令执行结果:'$?
说明:hello函数指定了函数返回值为333,由于260超出了0~255,所以需要对指定的返回值进行一次取模运算,所以退出状态码由333变更为77。
示例三
指定函数返回值,但返回值前发生命令报错
函数中一条命令执行报错并不会影响后续代码的执行
#!/bin/bash
hello(){
# echo "Hello World"
cho "Hello World"
echo "结束"
return 3
}
hello
echo '命令执行结果:'$?
运行以后再次输入echo $?
由于hello函数指定了退出状态码,所以第一次输出的退出状态码为指定的整数3;第二次退出状态码则取脚本中最后一条命令echo $?
命令的执行状态,由于脚本中的echo $?
成功执行,所以第二次读取的退出状态码为0。
示例四
使用exit退出程序
read -p '请输入成绩:' str
if [ $str -lt 100 ]
then
echo '正确:'$str
exit 0
else
echo '错误'
exit 111
fi
4.2 利用退出状态码实现命令的重试
思路:
1、 利用退出状态码,可以判断命令是否成功执行
2、 利用循环语句,可以实现命令的重试
3、 如果只设置退出状态码为0作为唯一的循环退出条件,可能出现死循环,所以最好增加最大重试次数的控制逻辑
4、$?是一个即使变化的值,如果需要多次使用,最好赋值给一个变量
#!/bin/sh
#记录重试次数
count=0
while [ 0 -eq 0 ]
do
echo ".................. job begin ..................."
# date
dat
flag=$?
echo "\$?"=${flag}
if [ ${flag} -eq 0 ]; then
echo "--------------- job complete ---------------"
break;
else
count=$[ ${count}+1 ]
if [ ${count} -eq 6 ];then
echo "--------------- job failed ---------------"
break;
fi
echo "............error occur, retry in 60 seconds,count=${count} .........."
# sleep 60
fi
done
运行结果 :
当退出状态码非0时,代码中[ 0 -eq 0 ]
和[${flag}-eq 0 ]
部分实现了重试功能;[${count}-eq 6 ]
部分实现了对重试逻辑不得超过6次的控制
4.3 小结
Shell退出状态码:
-
假如没有指定返回值,那么会用脚本的最后一个命令的执行状态,作为退出的状态码,支持用exit命令指定退出码。退出的状态码范围是0~255,如果自定义的退出码不在范围内,会对其执行取模运算;
-
假如执行的是一个有返回值的函数或者程序,那么执行结束的返回值会被当做当前函数或程序的退出状态值。