使用getopt处理参数
文章目录
- 使用getopt处理参数
- 1. shift 命令
- 1.1 删除一个参数
- 1.2 删除多个参数
- 1.3 多次执行 shift 参数
- 1.4 参数解析示例
- 1.5 优化处理
- 1.6 问题处理
- 2. getopt 命令
- 2.1 常用参数及示例
- 2.2 脚本参数优化示例
- 2.3 参数校验
- 3. 示例展示
- 4. eval 命令
- 4.1 示例
- 示例 1
- 示例 2
- 示例 3
- 示例 4
- 示例 5
使用getopt处理参数
getopt是用来解析,整理传入shell的命令行参数的命令
参考地址:B站传送门
1. shift 命令
shift的作用就是从头部删除参数,它可以在后面各跟一个数字参数表示删除几个参数示例:
shift 2表示删除两个参数
常见参数使用,可以使用
$@输入所有参数
[root@105 dongxx]# cat a.sh
#!/bin/bash# 输入所有参数
echo $@[root@105 dongxx]# sh a.sh a b c
a b c

1.1 删除一个参数
使用
shift命令之后会发现第一个参数a没了
[root@105 dongxx]# cat a.sh
#!/bin/bashshift# 输入所有参数
echo $@
[root@105 dongxx]# sh a.sh a b c
b c

1.2 删除多个参数
使用
shift 2删除两个参数
[root@105 dongxx]# cat a.sh
#!/bin/bashshift 2# 输入所有参数
echo $@
[root@105 dongxx]# sh a.sh a b c d
c d

1.3 多次执行 shift 参数
shift参数还可以多次执行,可以多次执行删除多个参数
[root@105 dongxx]# cat a.sh
#!/bin/bashshift 2
shift# 输入所有参数
echo $@
[root@105 dongxx]# sh a.sh a b c d e
d e

1.4 参数解析示例
需求:处理参数
-a -name zhangsan -age 18,需要分开输出为-a-name zhangsan-age 18
[root@105 dongxx]# cat a.sh
#!/bin/bash
# 参数:-a -name zhangsan -age 18# -a 为第一个参数,可以直接使用 $1
echo $1# 输出 $1 之后,使用 shift 删除第一个参数,那么后面的参数就是从 $1 开始了,所以这里的 $1 和 $2 就是 -name 和 zhangsan
shift
echo $1 $2# 因为 -name 选项和它的参数 zhangsan 占了两个位置,那么就需要 shift 两次了,同理,这里的 $1 就是 -age 选项 $2 就是 18 了
shift 2
echo $1 $2
[root@105 dongxx]# sh a.sh -a -name zhangsan -age 18
-a
-name zhangsan
-age 18

1.5 优化处理
上述案例中没有考虑参数顺序问题,如果参数顺序有不一样输出结果也就乱了,所以在脚本中不仅要能挨个拿到选项和参数,还要根据选项是有参还是无参来控制
shift的数量,而且也并不是每个选项参数一定要用,也就是说选项参数数量是不固定的。这样我们可以使用循环来处理。示例:
[root@105 dongxx]# cat a.sh
#!/bin/bash
# 参数:-a -name zhangsan -age 18while true; docase "$1" in-a)echo "-a 选项"shift;;-name)echo "-name 选项,参数为 $2"shift 2;;-age)echo "-age 选项,参数为 $2"shift 2;;*)echo "非法参数"exit 1esac
done
[root@105 dongxx]# sh a.sh -a -name zhangsan -age 18
-a 选项
-name 选项,参数为 zhangsan
-age 选项,参数为 18
非法参数

上述脚本中有个问题,在没有参数时会提示
非法参数,且参数为-a -name zhangsan -age 18时,仍提示非法参数[root@105 dongxx]# sh a.sh 非法参数
问题解析:
#!/bin/bash
# 参数:-a -name zhangsan -age 18while true; docase "$1" in-a)echo "-a 选项"shift;;-name)echo "-name 选项,参数为 $2"shift 2;;-age)echo "-age 选项,参数为 $2"shift 2;;*)echo "非法参数"exit 1esac
done# 当前脚本在匹配完成会后删除了所有参数,最后 $1 匹配为空会走到最后的 * 匹配,所以就会输出“非法参数”
问题处理:
#!/bin/bash
# 参数:-a -name zhangsan -age 18# 这里我们可以使用 set 命令来处理,set 命令可以用来指定一个结束标记
set -- "$@" --
# 参数说明:
# set -- 为删除所有参数,在 -- 后面可以设置自定义参数,最后在添加一个 -- 作为结束标记
# 输出查看
echo "\$@: "$@while true; docase "$1" in-a)echo "-a 选项"shift;;-name)echo "-name 选项,参数为 $2"shift 2;;-age)echo "-age 选项,参数为 $2"shift 2;;--)break;;*)echo "非法参数"exit 1esac
done
测试
[root@105 dongxx]# cat a.sh
#!/bin/bash
# 参数:-a -name zhangsan -age 18# 这里我们可以使用 set 命令来处理,set 命令可以用来指定一个结束标记
set -- "$@" --
# 参数说明:
# set -- 为删除所有参数,在 -- 后面可以设置自定义参数,最后在添加一个 -- 作为结束标记
# 输出查看
echo "\$@: "$@while true; docase "$1" in-a)echo "-a 选项"shift;;-name)echo "-name 选项,参数为 $2"shift 2;;-age)echo "-age 选项,参数为 $2"shift 2;;--)break;;*)echo "非法参数"exit 1esac
done
[root@105 dongxx]# sh a.sh
$@: --
[root@105 dongxx]# sh a.sh -a -name zhangsan -age 18
$@: -a -name zhangsan -age 18 --
-a 选项
-name 选项,参数为 zhangsan
-age 选项,参数为 18

1.6 问题处理
上述测试脚本参数都是约定好的,但是在实际使用过程中可能会出现没有安装约定的方式传参的问题
示例:
-a aaa -name zhangsan -age 18,那这时候参数的顺序位置就会有问题。这时我们就可以使用getopt来处理了
2. getopt 命令
2.1 常用参数及示例
常用命令参数
参数 说明 -o 指定解析段格式选项 -l 指定要解析的长格式选项 – 分割真正需要解析的参数 示例:
[root@105 dongxx]# getopt -o a -l name:,age: -- -a --name zhangsan --age 18-a --name 'zhangsan' --age '18' --# 参数说明:-o 后跟上短格式选项-l 后跟上长格式选择,对于有参数的选项需要再参数后加个冒号,多个长格式选项用逗号隔开-- 后跟上真正需要解析的参数,而且 getopt 要求长格式选项需要使用 -- ,所以需要在选项前加上 --解析成功后会在参数最后默认加上 -- 的结束标记
测试给段格式选项
-a增加参数aaa,结果是没有参数输出,因为getopt知道-a选项是无参选项,所以它将跟在a后面的参数移动到了结束标记之后,在之前的脚步中是需要--则跳出循环,所以结束标记之后的参数是不会被处理的
[root@105 dongxx]# getopt -o a -l name:,age: -- -a aaa --name zhangsan --age 18-a --name 'zhangsan' --age '18' -- 'aaa'

2.2 脚本参数优化示例
使用
getopt处理一下就能解决参数位置错误导致的参数解析错乱的问题
[root@105 dongxx]# cat a.sh
#!/bin/bash
# 参数:-a -name zhangsan -age 18# 使用 $(getopt -o a -l name:,age: -- "$@") 获取 getopt 处理后的参数信息,在使用 set -- 把这个结果设置后脚本的参数,由于 getopt 本身就有 -- 的结束标记,所以下面的 set -- "$@" -- 就不需要了
set -- $(getopt -o a -l name:,age: -- "$@")# 这里我们可以使用 set 命令来处理,set 命令可以用来指定一个结束标记
# set -- "$@" --
# 参数说明:
# set -- 为删除所有参数,在 -- 后面可以设置自定义参数,最后在添加一个 -- 作为结束标记
# 输出查看
echo "\$@: "$@while true; docase "$1" in-a)echo "-a 选项"shift;;# 为了兼容 getopt 长格式的设置,这里需要改成 --name--name)echo "-name 选项,参数为 $2"shift 2;;--age)echo "-age 选项,参数为 $2"shift 2;;--)break;;*)echo "非法参数"exit 1esac
done
[root@105 dongxx]# sh a.sh -a --name zhangsan --age 18
$@: -a --name 'zhangsan' --age '18' --
-a 选项
-name 选项,参数为 'zhangsan'
-age 选项,参数为 '18'
[root@105 dongxx]# sh a.sh -a aa --name zhangsan --age 18
$@: -a --name 'zhangsan' --age '18' -- 'aa'
-a 选项
-name 选项,参数为 'zhangsan'
-age 选项,参数为 '18'
执行测试

2.3 参数校验
当我们正常传参时,示例:
sh a.sh -a --name zhangsan --age 18没有问题。如果我们将有参的选项的参数去掉sh a.sh -a --name zhangsan --age那么就会报错
[root@105 dongxx]# sh a.sh -a --name zhangsan --age
getopt: option '--age' requires an argument
$@: -a --name 'zhangsan' --
-a 选项
-name 选项,参数为 'zhangsan'

问题:
上述脚本中也有个问题,就是报错之后仍然会继续执行。
解决:
修改脚本,在开头设置一个
set -e让他需要非 0 状态吗自动退出。如果单纯只增加set -e命令,脚本同样会继续往下执行,因为在上述脚本中getopt是在set --中执行的,getopt报错,但是set --是正常执行的,所以结果就不是一个非 0 状态。所以需要将getopt提取出来单独处理。
[root@105 dongxx]# cat a.sh
#!/bin/bash
# 参数:-a -name zhangsan -age 18set -e# 将 getopt 提取出来赋值变量,那么校验失败后,set -e 就会检测到非 0 状态从而退出脚本
args=$(getopt -o a -l name:,age: -- "$@")
set -- $args# 使用 $(getopt -o a -l name:,age: -- "$@") 获取 getopt 处理后的参数信息,在使用 set -- 把这个结果设置后脚本的参数,由于 getopt 本身就有 -- 的结束标记,所以下面的 set -- "$@" -- 就不需要了
# set -- $(getopt -o a -l name:,age: -- "$@")# 这里我们可以使用 set 命令来处理,set 命令可以用来指定一个结束标记
# set -- "$@" --
# 参数说明:
# set -- 为删除所有参数,在 -- 后面可以设置自定义参数,最后在添加一个 -- 作为结束标记
# 输出查看
echo "\$@: "$@while true; docase "$1" in-a)echo "-a 选项"shift;;# 为了兼容 getopt 长格式的设置,这里需要改成 --name--name)echo "-name 选项,参数为 $2"shift 2;;--age)echo "-age 选项,参数为 $2"shift 2;;--)break;;*)echo "非法参数"exit 1esac
done
[root@105 dongxx]# sh a.sh -a --name zhangsan --age
getopt: option '--age' requires an argument

3. 示例展示
命令展示示例:
[root@105 dongxx]# getopt -o a:bc: -l name:,age:,man -- -a 1 -b -c 2 --name zhangsan --age 18 --man-a '1' -b -c '2' --name 'zhangsan' --age '18' --man --
脚本展示示例:
#!/bin/bash# 问题:在没有 -o 参数时会报错,这是为什么
# args=$(getopt -l name:,age:,address:,user:,passwd: -- "$@")args=$(getopt -o -a: -l name:,age:,address:,user:,passwd: -- "$@")if [[ $? != 0 ]]; thenecho "请输出正确参数"exit 1
fiecho "args: "$args
# 问题:这里为什么需要使用 eval ,暂时还不知道
eval set -- "$args"# set -- "$args"while true ;doecho "\$1: "$1case "$1" in--name)if [[ -z "$NAME" ]]; thenNAME=$2fishift 2;;--age)if [[ -z "$AGE" ]]; thenAGE=$2fishift 2;;--address)if [[ -z "$ADDRESS" ]]; thenADDRESS=$2fishift 2;;--user)if [[ -z "$USER" ]]; thenUSER=$2fishift 2;;--passwd)if [[ -z "$PASSWD" ]]; thenPASSWD=$2fishift 2;;--)break;;*)echo "参数错误,请检查"exit 1;;esac
doneecho "name: " $NAME ", age: " $AGE ", address: "$ADDRESS ", user: "$USER ", passwd: "$PASSWD

4. eval 命令
参考地址1
参考地址2
eval内置命令:
功能:当Shell程序执行到eval语句的时候,Shell读入参数args,并将它们组合成一个新的命令,然后执行。也就是重新运算求出参数的内容。eval可以读取一连串的参数,然后依据参数本身的特性来执行。参数不限数目,彼此之间用分号分开。 eval会对后面的命令进行两遍的扫描,如果第一遍扫描后,命令是普通命令,则执行此命令;如果命令中含有变量的间接引用,则保证间接引用的语义。也就是说,eval语句将会首先扫描命令行进行所有的置换,然后再进行该命令。因此,eval命令适合用于那些一次扫描无法实现其功能的变量。
eval执行分两个步骤:
第一步:执行变量的替换。
第二步:执行替换后的命令
4.1 示例
示例 1
[root@105 1]# cat a.sh
#!/bin/bashecho "111 "\$$#
echo -e "\n"
echo "=============="
echo -e "\n"
eval "echo 2222 \$$#"
[root@105 1]# sh a.sh aa bb
111 $2==============2222 bb

脚本说明:
\$$#:$#是表示传参个数,\$表示转义,显示为普通字符$所以第一次输出\$$#只进行了第一步的变量替换, 结果为$2 使用
eval之后则进行了两次扫描,第一次是$#变量的替换,结果为$2,然后再执行替换后的命令$2,则结果显示$2的值bb
如果我们知道参数的个数,输入两个参数 aa bb,我们可以使用 $2 来查看最后一个参数 bb。但是如果我们不知道参数个数,还想查看最后一个参数怎么办呢?我们想到 $#,传给Shell脚本的个数,echo $# 显示的其实是参数个数,而使用 eval echo "$$#" 才显示最后一个参数。和上述示例一样。
示例 2
[root@105 1]# cat test
Hello World
[root@105 1]# aa="cat test"
[root@105 1]# echo $aa
cat test
[root@105 1]# eval $aa
Hello World

脚本说明:
eval命令对后面的命令进行了两次扫描,第一次将$aa替换为cat test,第二次执行cat test。- 这些需要进行两次扫描的变量有时也称为复杂变量。不过这些变量并不复杂。
示例 3
在
file文件中,有两列数据,第一列对应KEY,第二列对应VALUE,使用eval命令将KEY和VALUE的值对应起来,从文件中读取。
[root@105 1]# cat file
NAME chang
AGE 28
SEX nan
[root@105 1]# cat a.sh
#!/bin/bash
while read KEY VALUE
doeval "${KEY}=${VALUE}"
done < file
echo "NAME: "$NAME", AGE: "$AGE", SEX:" $SEX
[root@105 1]# sh a.sh
NAME: chang, AGE: 28, SEX: nan
[root@105 1]#
[root@105 1]# sh -x a.sh
+ read KEY VALUE
+ eval NAME=chang
++ NAME=chang
+ read KEY VALUE
+ eval AGE=28
++ AGE=28
+ read KEY VALUE
+ eval SEX=nan
++ SEX=nan
+ read KEY VALUE
+ echo 'NAME: chang, AGE: 28, SEX:' nan
NAME: chang, AGE: 28, SEX: nan

脚本说明:
eval "${KEY}=${VALUE}"中eval第一次扫描获取变量${KEY}=${VALUE}的值,第二次进行赋值操作
示例 4
[root@105 1]# cat >a.sh<<EOF""
> #!/bin/bash
> x=100
> y=x
> eval echo \$$y
> eval $y=50
> echo $x
> eval echo \$$y
> EOF
[root@105 1]# cat a.sh
#!/bin/bash
x=100
y=x
eval echo \$$y
eval $y=50
echo $x
eval echo \$$y
[root@105 1]#
[root@105 1]# sh a.sh
100
50
50

上面例子中的
eval echo \$$y首先被读取,然后被执行:在读取的过程中,$y会被替换成x,所以读取的结果是echo $x;执行echo $x的输出就是打印了变量x的值。同理,eval $y=50会被解析成x=50,然后执行x=50的结果就是为变量x赋值。
示例 5
执行复杂的字符串形式的命令
[root@105 1]# cat a.sh
#!/bin/bash
dirpath=/root/1
simple_cmd="ls -l $dirpath"
complex_cmd="ls -l $dirpath | awk -F ' ' '{print \$9}'"
echo '=========================='
echo '========Simple Cmd========='
echo '=========================='
eval $simple_cmd
echo '-----------------------------------'
$simple_cmd
echo '==========================='
echo '========Complex Cmd========='
echo '==========================='
eval $complex_cmd
echo '-----------------------------------'
$complex_cmd
[root@105 1]#
[root@105 1]# sh a.sh
==========================
========Simple Cmd=========
==========================
total 8
-rw-r--r-- 1 root root 467 Jul 11 21:28 a.sh
-rw-r--r-- 1 root root 5 Jul 11 21:28 test
-----------------------------------
total 8
-rw-r--r-- 1 root root 467 Jul 11 21:28 a.sh
-rw-r--r-- 1 root root 5 Jul 11 21:28 test
===========================
========Complex Cmd=========
===========================a.sh
test
-----------------------------------
ls: cannot access |: No such file or directory
ls: cannot access awk: No such file or directory
ls: cannot access ': No such file or directory
ls: cannot access ': No such file or directory
ls: cannot access '{print: No such file or directory
ls: cannot access $9}': No such file or directory
/root/1:
total 8
-rw-r--r-- 1 root root 467 Jul 11 21:28 a.sh
-rw-r--r-- 1 root root 5 Jul 11 21:28 test

可以看到,在执行
$simple_cmd时,是否使用eval的效果是相同的。但是当我们执行一个稍微复杂一点(比如包含管道(Pipe))的字符串形式的命令时,如果不使用eval,执行会报错!
相关文章:
使用getopt处理参数
文章目录 使用getopt处理参数1. shift 命令1.1 删除一个参数1.2 删除多个参数1.3 多次执行 shift 参数1.4 参数解析示例1.5 优化处理1.6 问题处理 2. getopt 命令2.1 常用参数及示例2.2 脚本参数优化示例2.3 参数校验 3. 示例展示4. eval 命令4.1 示例示例 1示例 2示例 3示例 4…...
图像搜索技术在司法证据分析中的应用:思通数科大模型的创新实践
引言 在司法侦查过程中,图像和视频证据的分析对于案件的侦破至关重要。随着人工智能技术的快速发展,图像搜索技术已成为司法领域的关键工具。本文将探讨如何结合思通数科的大模型,利用图像搜索技术对案件中的图片或视频证据进行深度分析&…...
python使用多进程,传入多个参数?
先展示一下我的多进程代码: def process_image(image_path_list):# 获取模板以及类别名template_feature {}template_image cv2.imread(image_path_list)template_feature[curr_template_name] template_imageinput_image cv2.imread(img)template_feature[inp…...
李彦宏: 开源模型是智商税|马斯克: OpenAI 闭源不如叫 CloseAI
在 2024 年世界人工智能大会(WAIC 2024)上,百度创始人、董事长兼首席执行官李彦宏发表对开源模型的评价。 李彦宏认为:开源模型实际上是一种智商税,而闭源模型才是人工智能(AI)行业的未来。 马…...
怎么参与场外期权?场外期权交易要注意什么?
今天带你了解怎么参与场外期权?场外期权交易要注意什么?场外期权(OTC Options)是指在交易所之外进行的期权交易。与场内期权(交易所挂牌交易)不同,场外期权交易由交易双方私下协商确定合约条款&…...
Postman脚本炼金术:高级数据处理的秘籍
🤖 Postman脚本炼金术:高级数据处理的秘籍 Postman不仅是API测试的强大工具,它的脚本功能同样能够在数据处理方面大放异彩。无论是在请求之前设置环境,还是测试后验证结果,Postman的脚本都能提供强大的数据处理能力。…...
MySQL字符串相关数据处理函数
目录 1. 转大小写 2. 截取字符串 sunstr 3. 获取字符长度 4. 字符串拼接 concat 5. 去掉空白 trim 1. 转大小写 转大写:upper() 转小写:lower() 虽然MySQL不严格区分大小写,但是我们还是需要掌握这种大小写的操作以方便学习其他…...
最近查看了一些批处理文件的写法,整理了一些基础的命令符,大佬勿喷
1.Echo 命令 打开回显或关闭请求回显功能,或显示消息。 2. 命令 表示不显示后面的命令,但是会显示结果 3.Goto和: 命令 :定义标签,goto跳转到标签 4.Rem ::注释命令 ::不显示不执行,rem显示不执行 5.Pause 命令 暂停命…...
解决 Yarn 运行时的 Node.js 版本问题:一个详尽的指南
引言 Yarn 是一个流行的 JavaScript 包管理器,它与 Node.js 紧密集成,用于管理项目依赖。然而,在开发过程中,开发者可能会遇到 Node.js 版本不兼容的问题,这会导致 Yarn 运行时出错。本文将提供一个详细的指南&#x…...
SQL基础-DQL 小结
SQL基础-DQL 小结 学习目标:学习内容:SELECTFROMWHEREGROUP BYHAVINGORDER BY运算符ASC 和 DESC 总结 学习目标: 1.理解DQL(Data Query Language)的基本概念和作用。 2.掌握SQL查询的基本语法结构,包括SEL…...
冒泡排序与其C语言通用连续类型排序代码
冒泡排序与其C语言通用连续类型排序代码 冒泡排序冒泡排序为交换排序的一种:动图展示:冒泡排序的特性总结:冒泡排序排整型数据参考代码(VS2022C语言环境): 冒泡排序C语言通用连续类型排序代码对比较的方式更…...
Python爬虫并输出
1. Python爬虫并输出示例 下面是一个使用Python编写的简单网络爬虫示例,该爬虫将抓取某个网页(例如,我们假设为https://example.com,但请注意实际使用时我们需要替换为一个真实且允许抓取的网站)的标题(Ti…...
交叉熵损失函数的使用目的(很肤浅的理解)
第一种使用方法 import torch from torch import nn # Example of target with class indices loss nn.CrossEntropyLoss() input torch.randn(3, 5, requires_gradTrue) target torch.empty(3, dtypetorch.long).random_(5) output loss(input, target) output.backward(…...
MySQL:TABLE_SCHEMA及其应用
MySQL TABLE_SCHEMA及其应用 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite:http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/qq_28550263/ar…...
【MySQL】4.MySQL 的数据类型
MySQL 的数据类型 一.数据类型分类在这里插入图片描述二.注意点1.char VS varchar2.datetime VS timestamp3.enum 和 set 的使用方法 一.数据类型分类 二.注意点 1.char VS varchar char 的意义是直接开辟固定大小的空间,浪费磁盘空间,但是效率高varcha…...
STM32中断(NVIC和EXIT)
CM3 内核支持 256 个中断,其中包含了 16 个内核中断和 240个外部中断,并且具有 256 级的可编程中断设置。但STM32 并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有 76 个中断,包括16 个内核中断和 60 个可屏蔽中断&am…...
哈弗架构和冯诺伊曼架构
文章目录 1. 计算机体系结构 2. 哈弗架构(Harvard Architecture) 3. 改进的哈弗架构 4. 冯诺伊曼架构(Von Neumann Architecture) 5. 结构对比 1. 计算机体系结构 计算机体系结构是指计算机系统的组织和实现方式,…...
Python实现动态迷宫生成:自动生成迷宫的动画
文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Pygame定义迷宫生成类主循环 完整代码 引言 迷宫生成算法在游戏开发和图形学中有着广泛的应用。它不仅可以用于创建迷宫游戏,还可以用于生成有趣的图案。在这篇博客中,我们将使用Python…...
大学生暑假“三下乡”社会实践工作新闻投稿指南请查收!
近年来,大学生暑期“三下乡”社会实践工作方兴未艾,越来越多的大学生通过参与“三下乡”实践工作,走出校园,深入基层,体验农村生活,服务农民,促进农村经济社会发展,实现了理论与实践…...
MySQL InnoDB存储引擎
MySQL InnoDB存储引擎 InnoDB 存储引擎的优点:由于 InnoDB 存储引擎存储的数据量大,性能高,可以有效的保证数据安全等优点,在 MySQL 5.5 后称为了默认的存储引擎。 InnoDB 内存结构: 缓冲池(buffer poll&…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
