【shell 编程大全】数组,逻辑判断以及循环
数组,逻辑判断以及循环
1. 概述
大家好,我又来了。今天呢我们继续学习shell相关的知识。还是老样子我们先回顾下上一次【脚本交互 以及表达式】学习到的知识
- 登录shell 关联配置文件
- 什么是子shell
- umask 修改默认权限
- read 基础
- 表达式
- 简单计算表达式
- expr 计算
- bc 计算
- 测试 表达式
- 逻辑表达式
- 字符串表达式
- 文件表达式
- 数字表达式
- 测试进阶表达式
- 逻辑组合表达式
我们简单回顾了下上次学习的内容。废话不多说了,接下来让我们一起学习新的内容
2. 数组
2.1 格式定义
格式
# 在Shell中,用括号来表示数组,数组元素用“空格”符号分割开。定义数组的语法格式:
array_name=(value1 ... valuen)
格式解读
单行定义
array_name=(value0 value1 value2 value3)多行定义
array_name=(value0value1value2value3
)单元素定义
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
2.2 具体案例
单行定义案例
[vagrant@localhost test003]$ echo ${array1}[vagrant@localhost test003]$ array1=(11 22 33 44 55)
[vagrant@localhost test003]$ echo ${array1}
11
[vagrant@localhost test003]$ echo ${array1[@]}
11 22 33 44 55
[vagrant@localhost test003]$
多行定义案例
[vagrant@localhost test003]$ echo ${array2[@]}[vagrant@localhost test003]$ array2=()
[vagrant@localhost test003]$ array2=(
> aa
> bb
> cc
> dd
> )
[vagrant@localhost test003]$ echo ${array2[@]}
aa bb cc dd
[vagrant@localhost test003]$
单元素定义案例
[vagrant@localhost test003]$ echo ${array3[@]}[vagrant@localhost test003]$ array3[0]=bb
[vagrant@localhost test003]$ array3[1]=ff
[vagrant@localhost test003]$ array3[2]=ee
[vagrant@localhost test003]$ echo ${array3[@]}
bb ff ee
[vagrant@localhost test003]$
命令行定义案例
[vagrant@localhost test003]$ echo ${array4[@]}[vagrant@localhost test003]$ array4=$(ls ../)
[vagrant@localhost test003]$ echo ${array4[@]}
test001 test002 test003
[vagrant@localhost test003]$
2.3 多种取值方式
格式
基于索引找内容读取数组元素值可以根据元素的下标值来获取,语法格式如下:${array_name[index]}${array_name[@]:起始位置:获取数量}
注意:获取具体的元素内容,指定其下标值,从0开始获取所有的元素内容,下标位置写"@"或者"*"
实例
[vagrant@localhost test003]$ num_list=(123 234 345 456 567)
[vagrant@localhost test003]$ echo ${num_list[@]}
123 234 345 456 567
[vagrant@localhost test003]$ echo ${num_list[@]:1:3}
234 345 456
[vagrant@localhost test003]$
2.4 获取数组长度
格式
在变量前面添加符号#
${#num_list[0]}
实例
[vagrant@localhost test003]$ echo ${num_list[@]}
123 234 345 456 567
[vagrant@localhost test003]$ echo ${#num_list[@]}
5
[vagrant@localhost test003]$
2.5 获取系统所数组
格式
declare -a
具体实例
[vagrant@localhost test003]$ declare -a
declare -a BASH_ARGC='()'
declare -a BASH_ARGV='()'
declare -a BASH_LINENO='()'
declare -ar BASH_REMATCH='()'
declare -a BASH_SOURCE='()'
declare -ar BASH_VERSINFO='([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='()'
declare -a GROUPS='()'
declare -a PIPESTATUS='([0]="0")'
declare -a array1='([0]="11" [1]="22" [2]="33" [3]="44" [4]="55")'
declare -a array2='([0]="aa" [1]="bb" [2]="cc" [3]="dd")'
declare -a array3='([0]="bb" [1]="ff" [2]="ee")'
declare -a num_list='([0]="123" [1]="234" [2]="345" [3]="456" [4]="567")'
[vagrant@localhost test003]$
2.6 数组替换/ 数组删除
格式
元素内容替换:array_name[index]=值
注意:在修改元素的时候,index的值一定要保持准确元素部分内容替换,可以参考字符串替换格式:${array_name[index]/原内容/新内容}
注意:默认是演示效果,原数组未被修改,如果真要更改需要结合单元素内容替换删除单元素unset array_name[index]
删除整个数组unset array_name
具体案例
[vagrant@localhost test003]$ unset array6
[vagrant@localhost test003]$ array6=(11 22 aa bb cc ddd ggg)
[vagrant@localhost test003]$ echo ${array6}
11
[vagrant@localhost test003]$ echo ${array6[@]}
11 22 aa bb cc ddd ggg
[vagrant@localhost test003]$ array6[0]=99
[vagrant@localhost test003]$ echo ${array6[@]}
99 22 aa bb cc ddd ggg
[vagrant@localhost test003]$ array6[5]=${array6[5]/ddd/ert}
[vagrant@localhost test003]$ echo ${array6[@]}
99 22 aa bb cc ert ggg
[vagrant@localhost test003]$ unset array6[5]
[vagrant@localhost test003]$ echo ${array6[@]}
99 22 aa bb cc ggg
[vagrant@localhost test003]$ unset array6
[vagrant@localhost test003]$ echo ${array6[@]}[vagrant@localhost test003]$
3. 逻辑判断
3.1 if 判断
3.1.1 格式
单分支格式
单路决策 - 单分支if语句样式:if [ 条件 ]then指令fi特点:单一条件,只有一个输出
双分支格式
双路决策 - 双分支if语句样式:if [ 条件 ]then指令1else指令2fi特点:单一条件,两个输出
多分支格式
多路决策 - 多分支if语句样式:if [ 条件 ]then指令1elif [ 条件2 ]then指令2else指令3fi特点:n个条件,n+1个输出
单行格式
单行命令写法if [ 条件1 ]; then 指令1; elif [ 条件2 ]; then 指令2; ... ; else 指令n; fi
3.1.2 实例
单行实例
#!/bin/bash# 单个if 判断
gender="$1"if [ "${gender}" == "男" ]
thenecho "你是男的"exit
fiecho "你不是男的"
双分支实例
#!/bin/bash# 双分支实例gender="$1"if [ "${gender}" == "nan" ]
thenecho "你是男的"
elseecho "你是女的"
fi
多分支实例
#!/bin/bash# 多分支实例gender="$1"if [ "${gender}" == "nan" ]
thenecho "你是男的"
elif [ "${gender}" == "nv" ]
thenecho "你是女的"
elseecho "我不知道你的性别"
fi
3.1.3 经典实例
3.1.3.1 奇偶数 判断
#!/bin/bash# 计算判断# 引导客户输入一个数字
read -p "请输入一个数字" num# 判断是基数 还是 偶数
if (( ${num} % 2 == 0 ))
thenecho "你是偶数"
elseecho "你是奇数"
fi
3.1.3.2 正则 判断
#!/bin/bash# 表示正则判断read -p "您输入一个字符串: " stringif [[ ${string} == v* ]]
thenecho "你是满足以v开头的"
elseecho "你不满足以v开头"
fi
3.2 case 判断
格式
case 变量名 in值1)指令1;;...值n)指令n;;
esac
实例
#!/bin/bash# 进行case 练习判断type="$1"case ${type} in"1")echo "你是1";;"2")echo "你是2";;*)echo "你是几我也不知道";;
esac
3.3 for 循环
格式
循环逻辑语法解析:关键字 [ 条件 ]do执行语句done注意:这里的关键字主要有四种:for - 循环遍历一个元素列表while - 满足条件情况下一直循环下去until - 不满足条件情况下一直循环下去select - 一种特殊的循环遍历,侧重于遍历用户输入,一般结合case等语句使用
实例1:遍历命令列表
#!/bin/bash# 进行for循环for i in $(ls /)
doecho "您的路径是${i}"
done
实例2:遍历参数列表
查看脚本内容
[root@localhost ~]# cat for_arg_list.sh
#!/bin/bash
# 功能:脚本参数列表 for循环
for i in $@
doecho "列表元素: ${i}"
done脚本执行后效果
[root@localhost ~]# /bin/bash for_arg_list.sh 1 2 3
列表元素: 1
列表元素: 2
列表元素: 3
3.3.1 多种案例
案例1
#!/bin/bash# 进行循环案例for i in yuwen shuxue lishi
doecho "列表元素: ${i}"
done
案例2
#!/bin/bash# 循环for i in {1..3}
doecho "元素内容是: ${i}"
done
案例3
#!/bin/bash# 实现脚本参数遍历for i in $@
doecho "元素内容是: ${i}"
done
3.3.2 综合实践
随机生成用户
#!/bin/bash# 随机创建用户user_file="/tmp/user.txt"# 检查是否是文件
[ -f ${user_file} ] && > ${user_file}# 开始批量创建用户
for i in {1..5}
do# 创建密码pwd="aaa$RANDOM"# 创建用户sudo useradd user-${i}# 设置密码echo ${pwd} | passwd --stdin user-${i} > /dev/null 2>&1# 开始输出信息echo "创建账号是: user-${i}, 该用户的密码是: ${pwd}"echo -e "创建的账号是: \033[31;41muser-${i}\033[0m 该用户的密码是: \033[31;41m${pwd}\033[0m"done
#!/bin/bash# 进行批量的用户删除for i in {1..5}
dosudo userdel -r user-${i}echo "用户【user-${i}】删除成功"
done
对特定的网段的主机进行扫描
#!/bin/bash# 对特定ip进行扫描base_net=192.168.56
net_file='/tmp/host.txt'# 判断文件是否存在
if [ -f ${net_file} ]
thensudo echo '' > ${net_file}
fifor i in {1..100}
do# 开始检测主机host_status=$(ping -c1 -W1 ${base_net}.${i} > /dev/null 2>&1 && echo "UP" || echo "DOWN")sudo echo "${base_net}.${i} 主机状态: ${host_status}" >> ${net_file}sudo echo "${base_net}.${i} 主机状态: ${host_status}"
done# 输出信息
live_num=$(grep UP ${net_file} | wc)
unlive_num=$(grep DOWN ${net_file} | wc)echo -e "\e[31m${netsub}.0 网段主机存活情况\e[0m"
echo "------------------------------------"
echo -e "\e[32m${netsub}.0 网段存活主机数量: ${live_num}\e[0m"
echo -e "\e[32m${netsub}.0 网段异常主机数量: ${unlive_num}\e[0m"
3.3.3 循环赋值
#!/bin/bash# 进行循环赋值all_sum=0
odd_sum=0
even_sum=0for i in {1..100}
dolet all_sum+=i
donefor i in {1..100..2}
dolet odd_sum+=i
donefor i in {0..100..2}
dolet even_sum+=i
doneecho -e "所有的数字之和是: \033[31m${all_sum}\033[0m"
echo -e "所有的数字之和是: \033[31m${odd_sum}\033[0m"
echo -e "所有的数字之和是: \033[31m${even_sum}\033[0m"
3.3.4 (()) 版的双括号的语法
#!/bin/bash# 使用特殊符号(()) 来进行计算all_sum=0for ((i=0; i<=100; i+=1))
dolet all_sum+=i
doneecho -e "计算结果是: \033[31m${all_sum}\033[0m"
3.3.4.1 综合实践:命令行进度条数字
#!/bin/bash# 实现数字进度条for ((i=0; i<=100; i+=1))
do// 防止信息输出的叠加,采用\e[4D,每次输出信息的时候,光标左移4个位置,信息不会出现叠加printf "\e[4D%3d%%" $isleep 0.1
done
3.3.4.2 综合实践:实现进度条
#!/bin/bash# 实现数字进度条str="#"
arr=("|" "/" "-" "\\")for ((i=0; i<=50; i+=1))
dolet index=i%4printf "[%-50s][%d%%]%c\r" "$str" "$(($i*2))" "${arr[$index]}"sleep 0.2str+="#"
doneecho ""
3.3.4.3 综合实践:保存数字最大值 以及最小值
#!/bin/bash
# 设定随机数比大小# 设定基本变量
declare -i min max
declare -a nums# 设定大小比较
for ((i=0;i<10;i++))
do# 将随机数添加到数组中nums[$i]=$RANDOM# 设定初始值[ $i -eq 0 ] && min=${nums[0]} max=${nums[0]}# 设定最大值[ ${nums[$i]} > $max ] && max=${nums[$i]}# 设定最小值[ ${nums[$i]} < $min ] && min=${nums[$i]}
done
echo -e "\e[31m 随机数的统计信息\e[0m"
echo "------------------------------"
echo -e "\e[32m所有的随机数:${nums[@]}"
echo -e "最大的随机数:${max}"
echo -e "最小的随机数:${min}\e[0m"
3.4 while 循环
基础语法
场景:只要条件满足,就一直循环下去while [ 条件判断 ]do执行语句done
具体实例
#!/bin/bash# 通过while 循环来执行all_num=0
odd_num=0
even_num=0i=0
while (( i <= 100 ))
dolet all_num+=ilet i++
donei=0
while ((i<=100))
do((odd_num+=i))((i+=2))
donei=1
while ((i<=100))
do((even_num+=i))((i+=2))
doneecho "累加的和是:${all_num}"
echo "奇数累加的和是: ${odd_num}"
echo "偶数累加的和是: ${even_num}"
3.4.1 while read 用法
格式
while中有一种特殊的语法,while read line 它可以从文本中逐行读取相关的内容,然后存储到一个临时变量line中,然后我们后续就可以逐行对文本内容进行操作
样式1: cat提前读
cat a.log | while read line
do echo "File: ${line}"
done
实例1
#!/bin/bash# 通过while read 逐行读取i=0env | while read line
do((i+=1))echo "第${i}行内容是: ${line}"
done
实例2
exec 0< a.log
while read line
do echo "${line}"
done
实例3
while read line
doecho "File: ${line}"
done < a.log
3.5 until循环
使用方式跟while保持一致。
格式
场景:只要条件不满足,就一直循环下去until [ 条件判断 ]do执行语句done
3.6 select 条件选择
语法格式
select 变量名 in input_list
do 循环语句
done
语法解读:1 select 从 input_list 获取相关的值,然后输出到一个菜单列表,元素格式如下:序号) 菜单条目2 用户输入信息的标识使用PS3 的值,默认值是#?。我们可以定制PS3环境变量3 如果用户输入菜单序号,则输出菜单内容4 select的退出方式有很多种强制退出:Ctrl+D 组合键普通退出:结合break方式
实例1
#!/bin/bash# 通过select 进行简单选择echo "您喜欢的系统是:"
select osname in "HarmonyOS" "Linux" "Windows" "Ubuntu"
doecho "您选择的系统是: ${osname}"exit
done
实例2
#!/bin/bash# 修改输入指令PS3='请选择菜单序号: 'echo "请输入您喜欢的系统: "
select osname in "os" "linux" "window"
doecho "您选择的操作系统是: ${osname}"exit
done
相关文章:
【shell 编程大全】数组,逻辑判断以及循环
数组,逻辑判断以及循环1. 概述 大家好,我又来了。今天呢我们继续学习shell相关的知识。还是老样子我们先回顾下上一次【脚本交互 以及表达式】学习到的知识 登录shell 关联配置文件什么是子shellumask 修改默认权限read 基础表达式 简单计算表达式expr 计…...
Android13 Bluetooth更新
目录 Android 13 版本说明 LE Audio 代码更新 Android 12代码路径 Android 13代码路径 Android 13 版本说明 里面对蓝牙更新的描述较少,一出提到蓝牙的一...
手工测试混了5年,年底接到了被裁员的消息....
大家都比较看好软件测试行业,只是因为表面上看起来:钱多事少加班少。其实这个都是针对个人运气好的童人才会有此待遇。在不同的阶段做好不同阶段的事情,才有可能离这个目标更近,作为一枚软件测试人员,也许下面才是我们…...
Umi框架
什么是 umi umi 是由 dva 的开发者 云谦 编写的一个新的 React 开发框架。umi 既是一个框架也是一个工具,可以将它简单的理解为一个专注性能的类 next.js 前端框架,并通过约定、自动生成和解析代码等方式来辅助开发,减少开发者的代码量。 u…...
教你学git
前言 git是一种用于多人合作写项目。详细说明如下 文章目录前言什么是版本控制?什么是 Git?它就属于人工版本控制器版本控制工具常见版本控制工具怎么工作的?git 文件生命周期状态区域安装配置-- global检查配置创建仓库工作流与基本操作查看…...
【工作笔记】syslog,kern.log大量写入invalid cookie错误信息问题
任务描述 错误出现出现过四五次,应该是诊断单元tf卡读写出问题导致下面这条告警一直高频写入到/var/log/下的syslog、kern.log、messages中 Nov 23 06:25:12 embest kernel: omap_hsmmc 48060000.mmc: [omap_hsmmc_pre_dma_transfer] invalid cookie: data->hos…...
【C++】多线程
多任务处理有两种形式,即:多进程和多线程。 基于进程的多任务处理是程序的并发执行。基于线程的多任务处理是同一程序的片段的并发执行 文章目录1. 多线程介绍2. Windows多线程1. 多线程介绍 每一个进程(可执行程序)都有一个主线…...
0202插入删除-算法第四版红黑树-红黑树-数据结构和算法(Java)
文章目录4 插入4.1 序4.2 向单个2-结点插入新键4.3 向树底部的2-结点插入新键4.4 向一棵双键树(3-结点)中插入新键4.5 颜色调整4.6 根结点总是黑色4.7 向树底部的3-结点插入新键4.8 将红链接在树中向上传递4.9 实现5 删除5.1 删除最小键5.2 删除6 有序性…...
vue 生成二维码插件 vue-qr使用方法
一、安装 npm install vue-qr --save二、引入 import VueQr from vue-qrcomponents:{VueQr,},三、使用 <vue-qr:text"dyQrcode":size"170":logoSrc"logo":margin"6":logoScale"0.2"></vue-qr>四、属性说明 …...
网络工程课(二)
ensp配置vlan 一、配置计算机ip地址和子网掩码 二、配置交换机LSW1 system-view [Huawei]sysname SW1 [SW1]vlan batch 10 20 [SW1]interface Ethernet0/0/1 [SW1-Ethernet0/0/1]port link-type access 将接口设为access接口 [SW1-Ethernet0/0/1]port default vlan 10 [SW1-E…...
Pytorch并行计算(三): 梯度累加
梯度累加 梯度累加(Gradient Accmulation)是一种增大训练时batch size的技巧。当batch size在一张卡放不下时,可以将很大的batch size分解为一个个小的mini batch,分别计算每一个mini batch的梯度,然后将其累加起来优…...
蓝桥杯入门即劝退(十八)最小覆盖子串(滑动窗口解法)
欢迎关注点赞评论,共同学习,共同进步! ------持续更新蓝桥杯入门系列算法实例-------- 如果你也喜欢Java和算法,欢迎订阅专栏共同学习交流! 你的点赞、关注、评论、是我创作的动力! -------希望我的文章…...
Android一~
进程和线程的区别https://zhuanlan.zhihu.com/p/60375108https://zhuanlan.zhihu.com/p/138689342线程池的用法和原理tcp三次握手和四次挥手、tcp基础http请求报文格式二叉树中序遍历(算法)activity启动模式OKhttp源码讲解Java修饰符Java线程同步的方法s…...
一月券商金工精选
✦研报目录✦ ✦简述✦ 按发布时间排序 国盛证券 “薪火”量化分析系列研究(二)-票据逾期数据中的选股信息 发布日期:2023-01-04 关键词:股票、票据、票据预期 主要内容:本文深入探讨了“票据持续逾期名单”这一…...
UML中常见的9种图
UML是Unified Model Language的缩写,中文是统一建模语言,是由一整套图表组成的标准化建模语言。UML用于帮助系统开发人员阐明,展示,构建和记录软件系统的产出。通过使用UML使得在软件开发之前, 对整个软件设计有更好的…...
使用SpringBoot实现无限级评论回复功能
评论功能已经成为APP和网站开发中的必备功能。本文采用springbootmybatis-plus框架,通过代码主要介绍评论功能的数据库设计和接口数据返回。我们返回的格式可以分三种方案,第一种方案是先返回评论,再根据评论id返回回复信息,第二种方案是将评论回复直接封装成一个类似于树的数据…...
Kafka 介绍和使用
文章目录前言1、Kafka 系统架构1.1、Producer 生产者1.2、Consumer 消费者1.3、Consumer Group 消费者群组1.4、Topic 主题1.5、Partition 分区1.6、Log 日志存储1.7、Broker 服务器1.8、Offset 偏移量1.9、Replication 副本1.10、Zookeeper2、Kafka 环境搭建2.1、下载 Kafka2.…...
[学习笔记]Rocket.Chat业务数据备份
Rocket.Chat 的业务数据主要存储于mongodb数据库的rocketchat库中,聊天中通过发送文件功能产生的文件储存于/app/uploads中(文件方式设置为"FileSystem"),因此在对Rocket.Chat做数据移动或备份主要分为两步,…...
【ZOJ 1090】The Circumference of the Circle 题解(海伦公式+正弦定理推论)
计算圆的周长似乎是一项简单的任务——只要你知道它的直径。但如果你没有呢? 我们给出了平面中三个非共线点的笛卡尔坐标。 您的工作是计算与所有三个点相交的唯一圆的周长。 输入规范 输入文件将包含一个或多个测试用例。每个测试用例由一条包含六个实数x1、y1、x…...
【go】slice原理
slice包含3个部分: 1.内存的起始位置 2.切片的大小(已经存放的元素数量) 3.容量(可以存放的元素数量) 使用make初始化切片会开辟底层内存,并初始化元素值为默认值,如数字为0,字符串为空 使用New初始化切片不会开辟底层数组&…...
ComfyUI-Manager终极指南:3个核心功能彻底解决AI工作流管理难题
ComfyUI-Manager终极指南:3个核心功能彻底解决AI工作流管理难题 【免费下载链接】ComfyUI-Manager ComfyUI-Manager is an extension designed to enhance the usability of ComfyUI. It offers management functions to install, remove, disable, and enable vari…...
保姆级教程:在ArcGIS Pro插件中集成你的自定义工具箱(以‘消除重复要素’为例)
从脚本到按钮:ArcGIS Pro插件开发实战指南 在GIS日常工作中,我们常常会遇到一些重复性的数据处理任务。比如数据质检环节的"消除重复要素"操作,虽然可以通过Python脚本实现,但每次都需要打开IDE或Python窗口执行代码&am…...
CVPR 2023反无人机数据集实战:用ModelScope上的开源模型快速上手目标检测
CVPR 2023反无人机数据集实战:用ModelScope上的开源模型快速上手目标检测无人机技术的普及带来了新的安全挑战,从隐私侵犯到关键设施威胁,反无人机技术正成为计算机视觉领域的热点。CVPR 2023反无人机竞赛提供的开源数据集和基线模型…...
别再手动改路径了!用LabVIEW + MATLAB Script做自动化测试,这份环境配置指南让你效率翻倍
LabVIEW与MATLAB深度整合:构建自动化测试系统的工程实践指南在工业自动化与测试测量领域,LabVIEW和MATLAB的组合堪称黄金搭档。LabVIEW擅长硬件接口和实时控制,而MATLAB在算法开发和数据分析方面具有无可比拟的优势。本文将深入探讨如何将两者…...
AI智能体到底强在哪?为什么大家开始从“养龙虾”转向“养马”
那么AI智能体的核心能力是什么? 1、理解需求 它能分析你的真实意图,而不是只看表面的文字,比如让它整理这个月的消费情况,它明白之后,会读取账单,做分类统计,生成总结,最后输出图表。…...
【UniApp小程序开发】解决无法使用Vue自定义指令的完美替代方案:权限组件封装
在 UniApp 开发中,你是否遇到过这样的困惑:明明在 Vue Web 项目中用得顺手的 v-permission 自定义指令,一到小程序端就完全失效?本文将深入剖析其原因,并提供一套可直接复用的组件化解决方案,让你在小程序中…...
GitLab External Wiki代理权限绕过漏洞深度解析
1. 这个漏洞不是“修个补丁”就能完事的——它暴露的是 GitLab 权限模型里一个被长期忽视的逻辑断层GitLab 安全漏洞 CVE-2025-2614,光看编号容易误以为是又一个常规的越权或 XSS 类型漏洞。但我在实际复现和审计过程中发现,它根本不是配置疏漏或代码拼写…...
保姆级避坑指南:在Ubuntu 22.04上搞定ROS2 Humble、PX4与Gazebo的联合仿真(附Empy版本降级)
保姆级避坑指南:Ubuntu 22.04下ROS2 Humble与PX4联合仿真的21个关键陷阱当你在Ubuntu 22.04上第一次尝试搭建ROS2 Humble、PX4与Gazebo的联合仿真环境时,可能会遇到比预期更多的挑战。这不是一个简单的"复制粘贴命令就能完成"的任务——版本冲…...
解密高校教师必会的Gemini 3.1 Pro五大科研隐藏技能:从论文评估到创新点锁定
各位同仁好,我是七哥。一个在高校里从事人工智能相关领域研究,钻研用大模型AI实操的学术人。可以和七哥交流学术写作或Gemini、GPT、Claude等大模型学术实操相关问题,多多交流,相互成就,共同进步。 科研路上,有人发完顶刊顺利晋升,有人还在为创新点抓耳挠腮。 大多数教…...
别再死磕USB HID了!用ESP32的Arduino框架手把手教你实现蓝牙鼠标键盘(附完整代码)
ESP32蓝牙HID实战:零基础打造自定义键盘鼠标 手里那块吃灰的ESP32开发板终于能派上用场了!上周我用它做了个无线演示控制器,在会议室里走着就能翻PPT,同事们都问是怎么实现的。其实秘诀就在于ESP32的蓝牙HID功能——不需要任何USB…...
