-vx shell_shell脚本--循环语句、函数和数组(概念及实例)

文章目录

shell脚本--循环语句、函数和数组

一、循环语句

1.1for语句的结构

1.2for语句应用实例

1.3for语句中使用(( ))

1.4while语句的结构

1.5双重循环

1.6until语句

二、shell函数

2.1函数的定义

2.2函数的作用范围

2.3递归函数

三、shell数组

3.1数组概述

3.2数组定义方法

3.3创建数组实例

四、shell脚本调试

shell脚本–循环语句、函数和数组

一、循环语句

1.1for语句的结构

●读取不同的变量值,用来逐个执行同一组命令

●for循环:指定次数循环;遍历:把集合中的每个元素挨个读取一遍

结构一:遍历集合

for 变量名 in 取值列表

do

命令序列

done

结构二:指定次数

for ((i=1;i<=5;i++))

do

命令序列

done

1.2for语句应用实例

实例1:

批量添加用户

用户名存放在user.txt文件中,每行一个

初始密码均设为123456

1c2bf10ff0c0aedee2e3ffd84925313e.png

实例2:

根据IP地址检查主机状态

IP地址存放在ipadds.txt文件中,每行一个

使用ping命令检测各主机的连通性

e84bf6c4c8d9c560c37396bb27f6de76.png

1.3for语句中使用(( ))

使用以下符号需要先加let或者两个小括号((sum+=$i))

符号后面可以跟整数,也可以跟调用的变量

++ 自身变量加1 – 自身变量减1

+=5 自身变量加5 -=5 自身变量减5

*=5 自身变量乘5 /=5 自身变量除5

%=5 自身变量取余5

实例1:

在屏幕上输出1-10(三种方式)

5ffa5fe9634c11adf15fb1d1b0257df5.png

b6792143fcd531db6ebbc95b0160fb67.png

a752dd6fccc8000d72a3af3f57afe0c7.png

实例2:

在屏幕上输出1-10;且输出循环结束后的数字

0a2c001d8bd2082d6a14f52c212c3a27.png

实例3:

将1-100中的奇数进行求和(四种语法)

注意:sum=0必须放在循环语句的上面(放在do下面每次sum都是从0开始)

3efca71614bfddf51363906ee2e5c470.png

1.4while语句的结构

重复测试某个条件,只要条件成立则反复执行

注意:

if条件成立只执行一次,而while成立了会反复执行,直到不成立

for可以先定义一个集合,再通过临时变量进行遍历

实例1:

批量创建5个用户:

用户名以stu开头,按数字进行编号,即stu1、stu2……

初始密码均为123123

afff1fe6445d1595c145acfaae929518.png

实例2:

输出1-100不能被3整除的数

f59c291aea5d61542d03d9f0661c1573.png

1.5双重循环

外层循环控制行;内层循环控制列

外层循环执行一次,内层循环执行一遍

打印一个直角三角形

echo -n ##不换行输出

echo -e ##支持加反斜线转义的字符(例如 \t 是水平制表符)

实例:

直角三角形

04c6b2a780e439386286435415799072.png

九九乘法口诀表

3650a5d77287480a78b7f49f2c7d5408.png

打印等腰三角形

ee2e843f2038bc63a90a2e85a660dc0f.png

1.6until语句

重复测试某个条件,只要条件不成立则反复执行;条件成立则退出循环

until 条件测试操作

do

命令序列

done

实例:

为指定用户发送在线消息

若用户不在线,则每6秒试一次,直至用户登录系统后再发送消息

用户名与消息通过位置参数传递给脚本

需求分析:

1.位置参数个数大于1;2.姓名是否属于系统用户

3.用户是否在线 until who 4.发送消息 echo “消息” | write 用户名

1f7e665c4c8e5a01d04400acf2f5119f.png

二、shell函数

2.1函数的定义

●将命令序列按格式写在一起

●可方便重复使用命令序列

●shell函数定义

[ function ] 函数名(){

命令序列

[return x] ##使用return或exit可以显式地结束函数

}

return:可以返回状态码或者数据(echo输出)

exit:只返回状态码

函数体外调用状态码或者值时:

return返回的是状态码,需要使用$?调用

echo 返回的是值,使用变量调用

传参:指位置变量

实例:

两个数字求和

通过sum(){ }定义函数

使用read命令交互输入两个数并求和

函数写好了要调用它才起作用!!

a31c35421bf3daa840d30dcfd7dde3a0.png

●调用函数的方法

函数名 [参数1] [参数2]

参数的表示方法:$ 1 $ 2 $ 3 ……$ {10} ${11}

9ed5788adf41bcdfb8d6d21b6fc6c979.png

2.2函数的作用范围

●函数在shell脚本中仅在当前shell环境中有效

●shell脚本中变量默认全局有效

●将变量限定在函数内部使用local命令

一旦在函数内通过local来定义变量,只能在函数体内识别

示例:

函数内部变量通过local实现

2854b4195a7ab2878aa91559fc33c031.png

local定义的函数体内的变量,可以通过函数体外先将函数赋值给一个变量,

再输出这个变量来引用local变量的值

4e726e426012f763f6597a307eecdf04.png

2.3递归函数

●调用自己本身的函数

实例:

递归遍历目录/var/log

通过定义递归函数list_files来实现

第一次循环:

$1 /var/log

$2 一个空格

第二次循环:

$1=$1/ $m /var/log/anaconda

$2=一个空格+$2 即两个空格

6bb54a90e06d3e331ff848474d44e21e.png

三、shell数组

3.1数组概述

数组:相同数据类型的集合 (例如整型、浮点型、字符串)

在内存中开辟了连续的空间

配合循环使用

举例:数组arr=(11 22 33 44)

数组名称:arr

数组元素:11,22,33,44

数组长度:4

数组下标:0 1 2 3(从0开始,例如33元素的下标值是2)

如何调用数组?

bef9eb311b54feb258fc10a0b2e50ae7.png

下面两种写法支持调用数组中所有或者单个元素

0b637a24880be631092bee1634d8a1d8.png

下面这种写法只支持调用数组中的所有元素,不支持单个元素

2362f28840c37c193b47c5d623ea1334.png

3.2数组定义方法

方法一:arr=(11 22 33 44)

方法二:arr=([0]=11 [1]=22 [2]=33 [3]=44)

方法三:list="11 22 33 44"

arr=($list)

方法四:arr[0]=11

arr[1]=22

arr[2]=33

方法四可用来替换掉数组中的某一个元素

数组包括的数据类型:

●数值类型

●字符类型

使用“”或‘’定义

3.3创建数组实例

需求:创建一个1-100的数组

2a43d91774b4f806641b767c11fe7c57.png

需求:创建一个存放(1-100)中奇数的数组

a8bac9ab9019f7d79f8be3562d5c8045.png

668d010fa83a538c62775f8b56e113ab.png

需求:创建可以自由添加自己想要的元素的数组

210a5002c24a65cac4c1a756e1f53ed7.png

3.4常见数组操作

●获取数组长度:

${#数组名[*]}

●读取某下标赋值:

${数组名[下标]}

●数组遍历:

for v in ${arr[@]}

do

echo "$v"

done

需求1:将班级中分数不满60分的加到60分

bb15732db0534ea508a6b2219a7dce61.png

需求2:将最低分输出

d04e687984e1f9619dd6dcd22500aeb0.png

需求2:将数组内的数字从小到大排序

使用冒泡排序

首先得了解a和b两个变量如何对调变量值:

a=10

b=20

方法(借助一个容器):

tmp=$ a

a=$ b

b=$tmp

c1e9fe3ecdf52372434b59844e61d333.png

●数组切片

${数组名[@]:起始位置:长度} 中间冒号隔开!!

ab9ea097b6d326dee0c8af9fd55c4148.png

●数组的替换 重点!!替换元素后再赋值给自己

${数组名[*]/查找字符/替换字符}

cf10efdb74dc1ac602d1f1dc4f35bb0f.png

●数组删除

unset

20abd3d053b1915de3d1177b24833a0d.png

注意!!

删除单个元素时,下标不会变,但是数组长度会减一

7f38de14f36d870a989316de53610a1c.png

c9476e7faedd17c96f21123f4f213e8a.png

需求:删除数组中小于60的元素,将剩下的元素输出

2b822eb5b6af4b62e6cc0ea6ec913f05.png

四、shell脚本调试

●echo命令 ##常用

●bash命令

命令语法

sh [-nvx] 脚本名

●set命令

set -x:开启调节模式

set +x:关闭调节模式

b041eba90de7de9553b841ed20b88c2a.png

检测结果如下,可以看到脚本执行的详细过程

[root@localhost ~]# sh -vx 60.sh

#!/bin/bash

arr=(45 85 65 25 78 52)

+ arr=(45 85 65 25 78 52)

i=0

+ i=0

set -x

+ set -x

for v in ${arr[*]}

do

if [ $v -lt 60 ];then

unset arr[$i]

fi

let i++

done

+ for v in '${arr[*]}'

+ '[' 45 -lt 60 ']'

+ unset 'arr[0]'

+ let i++

+ for v in '${arr[*]}'

+ '[' 85 -lt 60 ']'

+ let i++

+ for v in '${arr[*]}'

+ '[' 65 -lt 60 ']'

+ let i++

+ for v in '${arr[*]}'

+ '[' 25 -lt 60 ']'

+ unset 'arr[3]'

+ let i++

+ for v in '${arr[*]}'

+ '[' 78 -lt 60 ']'

+ let i++

+ for v in '${arr[*]}'

+ '[' 52 -lt 60 ']'

+ unset 'arr[5]'

+ let i++

set +x

+ set +x

echo ${arr[@]}

85 65 78

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
解释这段代码static void chassis_control_loop(chassis_move_t *chassis_move_control_loop) { fp32 max_vector = 0.0f, vector_rate = 0.0f; fp32 temp = 0.0f; fp32 wheel_speed[4] = {0.0f, 0.0f, 0.0f, 0.0f}; uint8_t i = 0; float position_error, speed_error; float position_output, speed_output; float current_position, current_speed; float target_position, target_speed; chassis_move_control_loop->vx_set=vx_set; chassis_move_control_loop->vy_set=vy_set; chassis_move_control_loop->wz_set=angle_set; chassis_vector_to_mecanum_wheel_speed(chassis_move_control_loop->vx_set, chassis_move_control_loop->vy_set, chassis_move_control_loop->wz_set, wheel_speed); if (chassis_move_control_loop->chassis_mode == CHASSIS_VECTOR_RAW) { for (i = 0; i < 4; i++) { chassis_move_control_loop->motor_chassis[i].give_current = (int16_t)(wheel_speed[i]); } } for (i = 0; i < 4; i++) { chassis_move_control_loop->motor_chassis[i].speed_set = wheel_speed[i]; temp = fabs(chassis_move_control_loop->motor_chassis[i].speed_set); if (max_vector < temp) { max_vector = temp; } } if (max_vector > MAX_WHEEL_SPEED) { vector_rate = MAX_WHEEL_SPEED / max_vector; for (i = 0; i < 4; i++) { chassis_move_control_loop->motor_chassis[i].speed_set *= vector_rate; } } for (i = 0; i < 4; i++) { PID_Calc(&chassis_move_control_loop->motor_speed_pid[i], chassis_move_control_loop->motor_chassis[i].speed, chassis_move_control_loop->motor_chassis[i].speed_set); } for (i = 0; i < 4; i++) { chassis_move_control_loop->motor_chassis[i].give_current = (int16_t)(chassis_move_control_loop->motor_speed_pid[i].out); } }
03-26
chassis_move_control_loop->motor_chassis[i].position_pid, chassis_move_control_loop->motor_chassis[i].speed_pid, chassis_move_control_loop->motor_chassis[i].position_get, chassis_move_control_loop->motor_chassis[i].speed_get, chassis_move_control_loop->motor_chassis[i].speed_set, &position_error, &speed_error, &position_output, &speed_output); current_position = chassis_move_control_loop->motor_chassis[i].position_get; current_speed = chassis_move_control_loop->motor_chassis[i].speed_get; target_position = chassis_move_control_loop->motor_chassis[i].position_set; target_speed = speed_output; if(chassis_move_control_loop->motor_chassis[i].position_pid.enable == 1) //PID启动 { chassis_move_control_loop->motor_chassis[i].give_current = PID_Calc(&chassis_move_control_loop->motor_chassis[i].position_pid, current_position, target_position); } else { chassis_move_control_loop->motor_chassis[i].give_current = PID_Calc(&chassis_move_control_loop->motor_chassis[i].speed_pid, current_speed, target_speed); } } } 该函数为底盘控制代码,主要实现底盘的位置和速度控制。 具体实现方法为: 1.根据控制指令,将底盘的速度向量转换为各个驱动电机的速度。 2.根据底盘模式选择不同的控制方式: 如果模式为 CHASSIS_VECTOR_RAW,直接将每个驱动电机的输出电流设置为对应速度。 3.根据电机的最大速度设置,对转换后的速度进行限制。 4.对每个驱动电机进行PID控制,计算出目标位置和目标速度,并根据位置控制或速度控制模式下达电机电流控制指令。 5.将目标速度和目标位置在PID计算中使用,并将计算出的电流控制指令转换为电机的输出电流。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值