目录
一.for循环
1.语法结构
1、for语句,也叫循环语句,也称之为for循环。
2、for语句也是一个结构复杂的语句,虽然简化代码,如用不熟也会适得其反。
3、for语句由三个部分组成:定义初始变量、循环条件、变化变量。
(1)列表循环
for i in {a..c}
do
echo $i
done
(2)不带循环列表
不带列表循环执行时由用户指定参数和参数的个数决定的
for 变量名
do
command
done
需要对变量“i”进行赋值,才会有运行结果,(任意赋值都可以)
(3)类c风格的for循环
for ((expr1;expr2;expr3))
do
command
done
expr1:定义变量并赋初值
expr2:决定是否循环
expr3:决定循环变量如何改变,决定循环什么时候退出
类C风格运算符用法
++ 自身变量+1
-- 自身变量-1
+=5 自身变量+5
-=5 自身变量-5
*=5 自身变量*5
/=5 自身变量/5
%=5 自身变量%5
案例:1-100之间的奇数和
2.while语句的结构
(1)语法结构
while 表达式
do
command
done
案例1:
案例二:1-100中不能整除3的数
(2)死循环
while死循环
while [ 1 -eq 1 ] //写一个永远为真的表达式,1等于1这个条件永远为真,所以这个脚本会一直循环下去
do
command
done
while true
do
command
done
while :
do
command
done
案例:猜数字,猜不对就一直猜
3.until循环
跟while相反,条件为假进入循环,条件为真退出循环
语法结构
until 表达式
do
command
done
案例:计算1-50的和,两种方法
1.
2.
4.循环控制语句
for循环一般会搭配条件判断语句和流程控制语句一起执行,那么就会出现需要跳过循环和中止循环的情况,控制循环的命令有以下3个
1、continue
继续,但不会执行循环体内下面的代码了,开始重新开始下一次循环
案例:打印1-5的数字,但不打印3
2、break
打断,马上停止本次循环,执行循环体外的代码
案例:1-10的数字,7后面的都不打印
3、exit
直接跳出程序,后面可跟状态返回码如exit 1等等
案例:
直接跳出程序所以不会执行最后的echo hi,并且返回码是100通过$?查看
二.shell函数
函数的定义:
1:
function 函数名 {
command
} //这是一种规范写法2:
函数名(){ //最常用因为最简洁
command
}
函数定义完之后并不会自动执行,需要调用才行,好处在于可以写一段功能代码作为函数,有需要就直接调用
定义的时候哪怕出现语法错误也没关系,不调用就不会报错
当然我们写函数最终目的还是为了调用,为了实现某个功能块
函数返回值:
return表示退出函数并返回一个退出值,脚本中可以用$?变量显示该值
使用原则:
1、函数一结束就取返回值,因为$?变量只返回执行的最后一条命令的退出状态码
2、退出状态码必须是0~255,超出时值将为取余256
1.函数的传参
函数的参数传递:当进行函数调用的时候,要填入与函数形式参数个数相同的实际参数,在程序运行的过程中,实参会将参数值传递给形参,这就是函数的参数传递。
案例:求两个数的和
2.函数的作用范围
在 Shell 脚本中函数的执行并不会开启一个新的子 Shell,而是仅在当前定义的 Shell 环境中有效。如果Shell脚本中的变量没有经过特殊设定,默认在整个脚本中都是有效的。在编写脚本时,有时需要将变量的值限定在函数内部,可以通过内置命令local来实现。函数内部变量的使用,可以避免函数内外同时出现同名变量对脚本结果的影响。
shell脚本中变量默认全局有效
local命令:将变量限定在函数内部使用
3.函数的参数
1.位置参数
一般是系统或用户提供的参数。
$[0-n],$0,表示指令本身,$1表示第一个参数,一次类推。
$0是内部参数,必须要有的,其后的就可有可无
2.内部参数
$# ----参数数目
$? ----上一个代码或者shell程序在shell中退出的情况,如果正常退出则返回0,反之为非0值。
$* ----所有参数的字符串
案例:
4.函数得返回值
函数的返回值,用return来自定义返回码
函数的返回值就是函数当中运行最后一条命令的状态码,默认成功为0,失败为非0值,可以通过$?查看
但是可以自己自定义返回码,用return1、return的值范围是0-255
2、遇到return即结束函数不会再往下执行
案例:
案例:
5.本地变量和全局变量
在脚本里定义的变量或者在函数体没有声明为本地变量的都为全局变量,意思是在当前shell环境都识别
如果需要这个变量只在函数中使用则可以在函数中用local关键字声明,这样即使函数体外有个重名的变量也没关系,不影响在函数体的使用
如果是用source执行脚本的话就能看出差别
案例:
6.函数的递归
函数自己调用自己的本身
案例:阶乘
三.数组的定义
1.定义
数组是存放相同类型数据的集合,在内存中开辟了连续的空间,通常配合循环使用
2.分类
普通数组:不需要声明直接定义,下标索引只能是整数
关联数组:需要用declare -A声明否则系统不识别,索引可以是字符串
3.定义方式
第一种:直接把要加入数组的元素用小括号括起来,中间用空格分开
num=(11 22 33 44)
${#num} 显示字符串长度
数组名= (value0 value1 value2)第二种:精确的给每一个下标索引定义一个值加入数组,索引数字可以不连续
num=([0]=55 [1]=66 [2]=77 [4]=88)第三种:先把要加入数组的元素全部先赋值给一个变量,然后引用这个变量加入到数组
list=“11 12 13 14”
num=($list)第四种 根据下标定义
数组名[0]=“11”
数组名[0]=“22”
数组名[0]=“33”数组名[0]="value"
数组名[1]="value"
数组名[2]="value
数组包括的数据类型
数值类型
字符类型:
使用“ ” 或 ‘ ’ 定义
4.冒泡排序
冒泡排序的基本思想是对比相邻的两个元素值,如果满足条件就交换元素值,
把较小的元素移动到数组前面,把大的元素移动到数组后面(也就是交换两个元素的
位置),这样较小的元素就像气泡一样从底部上升到顶部。
冒泡算法由双层循环实现,其中外部循环用于控制排序轮数,一般为要排序的数组长度减1,因为最后一次循环只剩下一个数组元素,不需要对比,同时数组已经完成排序了。而内部循环主要用于对比数组中每个相邻元素的大小,以确定是否交换位置,对比和交换次数随排序轮数而减少
#!/bin/bash
num=(90 70 60 40 50 30)
for ((i=0;i<${#num[*]};i++))
do
for ((j=i+1;j<${#num[*]};j++))
do
if [ ${num[$i]} -gt ${num[$j]} ]
then
temp=${num[$i]}
num[$i]=${num[$j]}
num[$j]=$temp
fi
done
done
echo ${num[*]