【shell脚本实战学习笔记】#1

shell脚本实战学习笔记#1

脚本编写场景需求:
编写一个比较数据大小的shell脚本,要求判断用户只能输入两位数字,不能是字符或其他特殊字符;并且在shell脚本中需要用到函数来控制执行顺序。

知识点:shell函数|正则匹配|全局变量

完整脚本:

#!/bin/bash#获取用户输入信息
number1=$1
number2=$2#判断用户输入的变量个数
check_input(){if [ $# -lt 2 ]; thenecho "当前输入的数值小于2,请输入需要比较的两个数字,两个数字之间用空格分开,谢谢合作!"exit 1elif [ $# -gt 2 ]; then echo "当前脚本仅支持比较两个数据,暂不支持两个以上数据的比较,请重新输入,谢谢合作!"exit 1fi
}#定义一个正在表达式来比较用户输入的是否为数字
re='^[+-]?[0-9]+([.][0-9]+)?$'#执行判断条件,分别判断两个输入是否为数字
check_Number(){if ! [[ $number1 =~ $re ]] || ! [[ $number2 =~ $re ]]; thenecho "您输入的信息有误,请输入两个数字,并用空格分开,谢谢!"exit 1fi
}#执行比较
judge_number(){echo "正在执行比较运算,请稍后..."sleep 5if [ $number1 -gt $number2 ]; thenecho "$number1大于判断值$number2"elif [ $number1 -eq $number2 ];then echo "$number1等于判断值$number2"elseecho "$number1小于判断值$number2"fi
}#主函数运行部分,定义执行哪些函数,以及执行的先后顺序
main(){check_input "$@"check_Numberjudge_number
}
#程序运行
main "$@" 

需求分析:

  1. 首先要让用户执行脚本时传入两个参数,因此给定$1 $2两个变量;
  2. 需求表明只能输入两个数字,因此判断逻辑有两层:判断变量个数为2个;判断输入内容是否为数字。
  3. 若满足两个判断条件,需要做数字比较的动作,这是脚本的核心需求。

实现过程:

#!/bin/bash# 定义变量
number=10# 条件判断
if [ $number -gt 10 ]; thenecho "数字大于10"
elif [ $number -eq 10 ]; thenecho "数字等于10"
elseecho "数字小于10"
fi

在这个脚本中,我们首先定义了一个变量number,然后通过if、elif和else语句检查这个变量的值,并打印出相应的信息。这里的-gt表示"大于"(greater than),-eq表示"等于"(equal)。
通过这个脚本我们初步实现了脚本最基本的比较功能,但这是跟一个固定数值去做比较,我们需要修改逻辑,让脚本实现两个数据的对比:

#!/bin/bash# 检查是否传入了两个参数
if [ $# -ne 2 ]; thenecho "请输入需要比较的两个数字,两个数字之间用空格分开,谢谢合作!"exit 1
fi# 获取参数
number1=$1
number2=$2# 进行比较
if [ $number1 -gt $number2 ]; thenecho "$number1 大于 $number2"
elif [ $number1 -eq $number2 ]; thenecho "$number1 等于 $number2"
elseecho "$number1 小于 $number2"
fi

在这个脚本中,我使用$#来检查传入的参数个数,如果不等于2(-ne 表示不等于),则打印提示信息并退出(exit 1)。之后,我用$1和$2来获取用户输入的两个数字,并进行比较。

但是我还想在这个脚本的基础上去做优化,现在能够判断的仅仅是输入的数据个数,我想添加判断条件判别用户输入的是否是字符或者其他东西,如果是字符,则抛出一个提示说目前不支持字符比较,请输入两位数字;如果输入的是特殊字符,则抛出提示说输入字符有误,请重新输入,因此继续调整:

#!/bin/bash# 判断用户输入的变量个数
if [ $# -lt 2 ]; thenecho "当前输入的数值小于2,请输入需要比较的两个数字,两个数字之间用空格分开,谢谢合作!"exit 1
elif [ $# -gt 2 ]; thenecho "当前脚本仅支持比较两个数据,暂不支持两个以上数据的比较,请重新输入,谢谢合作!"exit 1
fi# 定义变量
number1=$1
number2=$2# 判断输入是否为数字
re='^[+-]?[0-9]+([.][0-9]+)?$'
if ! [[ $number1 =~ $re ]] || ! [[ $number2 =~ $re ]]; thenecho "输入有误,请确保输入的是两个数字。"exit 1
fiecho "正在执行比较运算,请稍后..."
sleep 5# 进行比较
if [ $number1 -gt $number2 ]; thenecho "$number1大于判断值$number2"
elif [ $number1 -eq $number2 ]; thenecho "$number1等于判断值$number2"
elseecho "$number1小于判断值$number2"
fi
正则表达式(Regular Expression):这是一个强大的工具,用于匹配字符串模式。在这个脚本中,我使用了正则表达式'^[+-]?[0-9]+([.][0-9]+)?$'来检测输入是否为数字。这个表达式支持整数和浮点数,包括可选的正负号。条件判断:通过[[ $variable =~ $re ]]来判断变量$variable是否符合正则表达式$re定义的模式。如果不符合,我们打印错误消息并退出脚本。增强的用户体验和错误处理:通过确保输入为数字,脚本的鲁棒性和用户体验都得到了提升。如果用户输入了非数字,脚本会提供明确的反馈,而不是产生不可预测的行为。

正则表达式中的 在正则表达式中通常用来表示匹配的开始。它指定了模式必须出现在字符串的开头。

[±] 后的 ?:这个 ? 表示前面的字符组 [±](即正号或负号)是可选的。它表示正号或负号可以出现一次,或者不出现。

[0-9] 是匹配一个数字:[0-9] 表示匹配单个数字,即0到9之间的任意一个数字。

括号前面的 +:这个 + 表示前面的模式(括号中的模式)必须至少出现一次。在这个正则表达式中,[0-9]+ 表示至少有一个数字。

[0-9]+ 意思是匹配多个0-9之间的数字:[0-9]+ 表示匹配一个或多个数字。

正则表达式最后的 ?$ :这里的 ? 表示前面的分组(即括号内的模式)是可选的。$ 表示匹配的结束,确实和 ^ 是对应的。^ 表示开头,$ 表示结尾。

判断数据是否符合正则表达式的 if 语句中为什么是两个中括号:在 Bash 中,双中括号 [[ ]] 用于条件表达式。与单中括号 [ ] 相比,双中括号提供了更多的功能,比如模式匹配和正则表达式支持。在这种情况下,使用双中括号可以让我们利用正则表达式来检查变量值。

在 Bash 中,=~ 是一个特定的操作符,用于在条件表达式中执行正则表达式匹配。这个操作符仅在双中括号的条件测试([[ ]])中有效。

if [[ $variable =~ $re ]]; thenecho "匹配成功"
elseecho "匹配失败"
fi

这里, $variable是你要检查的字符串,$re 是一个正则表达式。如果 $variable符合这个正则表达式,那么表达式的结果为真(true),否则为假(false)。

注意点:

只在双中括号中有效:=~ 操作符只能在 [[ ]] 条件测试中使用。如果在单中括号 [ ] 中使用,它将不会按照预期工作。引用和不引用的区别:在使用正则表达式时,通常最好不要引用正则表达式变量(即使用 $re 而不是 "$re"),因为引用会使得表达式被当作普通字符串处理,而非正则表达式。Bash版本:请注意,这个特性在较老的 Bash 版本中可能不可用。它在 Bash 3.0 及以后的版本中是有效的。正则表达式的兼容性:Bash 使用的正则表达式是基于 POSIX ERE(扩展正则表达式),它与某些其他编程语言中使用的正则表达式(如Perl兼容正则表达式)略有不同。

所以,=~ 是一个强大的工具,用于在 Bash 脚本中进行模式匹配和数据验证。希望这些信息能帮助你更好地理解和使用这个特性!如果还有其他问题或疑惑,随时欢迎提问!

继续执行,将脚本内容用函数进行控制:

#!/bin/bash#获取用户输入信息
number1=$1
number2=$2#判断用户输入的变量个数
check_input(){if [ $# -lt 2 ]; thenecho "当前输入的数值小于2,请输入需要比较的两个数字,两个数字之间用空格分开,谢谢合作!"exit 1
elif [ $# -gt 2 ]; then echo "当前脚本仅支持比较两个数据,暂不支持两个以上数据的比较,请重新输入,谢谢合作!"exit 1
elseecho "正在执行比较运算,请稍后..."sleep 5
fi
}#定义一个正在表达式来比较用户输入的是否为数字
re='^[+-]?[0-9]+([.][0-9]+)?$'#执行判断条件,分别判断两个输入是否为数字
check_Number(){
if ! [[ $number1 =~ $re ]] || ! [[ $number2 =~ $re ]]; thenecho "您输入的信息有误,请输入两个数字,并用空格分开,谢谢!"exit 1
fi
}#执行比较
judge_number(){
if [ $number1 -gt $number2 ]; thenecho "$number1大于判断值$number2"
elif [ $number1 -eq $number2 ];then echo "$number1等于判断值$number2"
elseecho "$number1小于判断值$number2"
fi
}#主函数运行部分,定义执行哪些函数,以及执行的先后顺序
main(){
check_input
check_Number
judge_number
}
#程序运行
main

此时,我将脚本修改为了函数的方式,但是当我运行的时候我发现最开始number两个变量获取到了用户的输入,在执行check_input函数的时候我发现此时函数判断的$#是0,而不是用户实际输入的信息

问题分析:
特殊变量 $# 在函数中的作用域:在 Bash 脚本中,当你在函数内部使用 $# 时,它代表的是传递给该函数的参数个数,而不是传递给脚本的参数个数。由于你在调用 check_input 函数时没有传递任何参数,所以 $# 在 check_input 函数内部的值是 0。

解决方案:
在 main 函数中传递所有脚本参数:当调用 check_input 时,我们使用 $@ 来传递所有脚本参数。$@是一个特殊的变量,它代表了所有传递给脚本的参数,每个参数作为独立的引用字符串。

main() {check_input "$@"check_Numberjudge_number
}

继续执行发现仍然输出不对,因为单独在脚本的最末尾调用了main函数,此时main函数并未传递全局变量$@,因此在上述main函数中,实际并未传入用户输入的数据,继续修改如下:

#!/bin/bash# 其他函数定义...main() {# 在这里,"$@" 会包含传递给 main 函数的所有参数check_input "$@"check_Numberjudge_number
}# 脚本的最后调用 main 函数,并传递所有脚本参数
main "$@"

完整修改后的代码:

#!/bin/bash#获取用户输入信息
number1=$1
number2=$2#判断用户输入的变量个数
check_input(){if [ $# -lt 2 ]; thenecho "当前输入的数值小于2,请输入需要比较的两个数字,两个数字之间用空格分开,谢谢合作!"exit 1
elif [ $# -gt 2 ]; then echo "当前脚本仅支持比较两个数据,暂不支持两个以上数据的比较,请重新输入,谢谢合作!"exit 1
elseecho "正在执行比较运算,请稍后..."sleep 5judge_number "$@"
fi
}#定义一个正在表达式来比较用户输入的是否为数字
re='^[+-]?[0-9]+([.][0-9]+)?$'#执行判断条件,分别判断两个输入是否为数字
check_Number(){
if ! [[ $number1 =~ $re ]] || ! [[ $number2 =~ $re ]]; thenecho "您输入的信息有误,请输入两个数字,并用空格分开,谢谢!"exit 1
fi
}#执行比较
judge_number(){
if [ $number1 -gt $number2 ]; thenecho "$number1大于判断值$number2"
elif [ $number1 -eq $number2 ];then echo "$number1等于判断值$number2"
elseecho "$number1小于判断值$number2"
fi
}#主函数运行部分,定义执行哪些函数,以及执行的先后顺序
main(){
check_input "$@"
check_Number
#judge_number
}
#程序运行
main "$@" 

我的修改想法是:只有当用户输入的数据是两个的时候才去执行比较的动作,但是我这样修改,然后输入命令bash shell1.sh 20 aaa去执行这个脚本之后是如下的执行结果:

正在执行比较运算,请稍后...
shell1.sh: line 36: [: aaa: integer expression expected
shell1.sh: line 38: [: aaa: integer expression expected
20小于判断值aaa
您输入的信息有误,请输入两个数字,并用空格分开,谢谢!

问题分析:

逻辑顺序问题:从脚本和执行输出来看,judge_number 函数在 check_Number 函数之前被调用。这导致了即使输入的不是数字,judge_number 也会被执行。函数调用顺序:在 check_input 函数中直接调用了 judge_number 函数。这意味着只要输入的参数个数正确,无论参数是否为数字,judge_number 都会被执行。

解决方案:

脚本需要确保所有的检查都按正确的顺序进行:

首先检查参数个数:确保用户输入了两个参数。
然后检查参数类型:确保这两个参数都是数字。
最后执行比较操作。

代码修改思路:

根据上述逻辑,对脚本做如下修改:

在 main 函数中控制整体逻辑流程:先调用 check_input 检查参数个数,然后调用 check_Number 检查参数类型,最后调用 judge_number 进行比较。移除 check_input 中对 judge_number 的直接调用。确保 check_Number 在 judge_number 之前被调用。

再次修改后的脚本:

#!/bin/bash# 获取用户输入信息
number1=$1
number2=$2# 判断用户输入的变量个数
check_input() {if [ $# -lt 2 ]; thenecho "当前输入的数值小于2,请输入需要比较的两个数字,两个数字之间用空格分开,谢谢合作!"exit 1elif [ $# -gt 2 ]; then echo "当前脚本仅支持比较两个数据,暂不支持两个以上数据的比较,请重新输入,谢谢合作!"exit 1elseecho "正在执行比较运算,请稍后..."sleep 5fi
}# 定义正则表达式来比较用户输入的是否为数字
re='^[+-]?[0-9]+([.][0-9]+)?$'# 执行判断条件,分别判断两个输入是否为数字
check_Number() {if ! [[ $number1 =~ $re ]] || ! [[ $number2 =~ $re ]]; thenecho "您输入的信息有误,请输入两个数字,并用空格分开,谢谢!"exit 1fi
}# 执行比较
judge_number() {if [ $number1 -gt $number2 ]; thenecho "$number1大于判断值$number2"elif [ $number1 -eq $number2 ]; then echo "$number1等于判断值$number2"elseecho "$number1小于判断值$number2"fi
}# 主函数运行部分,定义执行哪些函数,以及执行的先后顺序
main() {check_input "$@"check_Numberjudge_number
}# 程序运行
main "$@"

如果我执行的数据是:

bash shell1.sh 20 aaa

脚本有如下输出:

正在执行比较运算,请稍后...
您输入的信息有误,请输入两个数字,并用空格分开,谢谢!

从输出内容来看,只要满足输入的信息是两个,不论是否为数字,都会正常执行比较的输出,
那么是不是可以将check_input函数中的else部分的输出放到judge_number函数里去?

修改建议:

简化 check_input 函数:只保留参数个数的检查,去掉 else 部分的输出。在 judge_number 函数中添加开始执行的提示:这样,只有在所有检查都通过后,才会显示这个提示并执行比较。

最后调整逻辑版本:

#!/bin/bash# 获取用户输入信息
number1=$1
number2=$2# 判断用户输入的变量个数
check_input() {if [ $# -lt 2 ]; thenecho "当前输入的数值小于2,请输入需要比较的两个数字,两个数字之间用空格分开,谢谢合作!"exit 1elif [ $# -gt 2 ]; then echo "当前脚本仅支持比较两个数据,暂不支持两个以上数据的比较,请重新输入,谢谢合作!"exit 1fi
}# 定义正则表达式来比较用户输入的是否为数字
re='^[+-]?[0-9]+([.][0-9]+)?$'# 执行判断条件,分别判断两个输入是否为数字
check_Number() {if ! [[ $number1 =~ $re ]] || ! [[ $number2 =~ $re ]]; thenecho "您输入的信息有误,请输入两个数字,并用空格分开,谢谢!"exit 1fi
}# 执行比较
judge_number() {echo "正在执行比较运算,请稍后..."sleep 5if [ $number1 -gt $number2 ]; thenecho "$number1大于判断值$number2"elif [ $number1 -eq $number2 ]; then echo "$number1等于判断值$number2"elseecho "$number1小于判断值$number2"fi
}# 主函数运行部分,定义执行哪些函数,以及执行的先后顺序
main() {check_input "$@"check_Numberjudge_number
}# 程序运行
main "$@"

以上内容就是基本实现一个数据比较的shell脚本需求,同时也确保了脚本的逻辑更加合理且健壮。

以上便是本次实战操作的所有过程了。

感谢您在百忙之中花费时间阅读本篇文章,期望对您的体能提升有所收获!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/241547.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

科研学习|论文解读——面向电商内容安全风险管控的协同过滤推荐算法研究

【论文完整内容详见知网链接】: 面向电商内容安全风险管控的协同过滤推荐算法研究 - 中国知网 (cnki.net) 面向电商内容安全风险管控的协同过滤推荐算法研究* 摘 要:[目的/意义]随着电商平台商家入驻要求降低以及商品上线审核流程简化,内容安…

Centos安装vsftpd:centos配置vsftpd,ftp报200和227错误

一、centos下载安装vsftpd(root权限) 1、下载安装 yum -y install vsftpd 2、vsftpd的配置文件 /etc/vsftpd.conf 3、备份原来的配置文件 sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.backup 4、修改配置文件如下:vi /etc/vsftpd.conf …

体验一下 CodeGPT 插件

体验一下 CodeGPT 插件 0. 背景1. CodeGPT 插件安装2. CodeGPT 插件基本配置3. (可选)CodeGPT 插件预制提示词原始配置(英文)4. CodeGPT 插件预制提示词配置(中文)5. 简单验证一下 0. 背景 看到B站Up主 “wwwzhouhui” 一个关于 CodeGPT 的视频,感觉挺有意思&#…

SpringMVC:整合 SSM 中篇

文章目录 SpringMVC - 04整合 SSM 中篇一、优化二、总结三、说明注意: SpringMVC - 04 整合 SSM 中篇 一、优化 在 spring-dao.xml 中配置 dao 接口扫描,可以动态地实现 dao 接口注入到 Spring 容器中。 优化前:手动创建 SqlSessionTempl…

STM32实现三个小灯亮

led.c #include"led.h"void Led_Init(void) {GPIO_InitTypeDef GPIO_VALUE; //???RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//???GPIO_VALUE.GPIO_ModeGPIO_Mode_Out_PP;//???? ????GPIO_VALUE.GPIO_PinGPIO_Pin_1|GPIO_Pin_2|GPIO_P…

spring-validation实现分组校验

文章目录 前言实际开发可能会使用到分组校验maven添加依赖简单使用高级应用分组自定义分组组合分组 源码地址 前言 JSR 303中提出了Bean Validation,表示JavaBean的校验,Hibernate Validation是其具体实现,并对其进行了一些扩展,…

Arduino上U8g2库显示中文的经历

u8g2自带很多中文库&#xff1b;但是向u8g2_font_wqy12_t_chinese3 比较全的应该是u8g2_font_wqy12_t_gb2312 这个&#xff0c;只是我还没有调用成功 这个库&#xff0c;中文就显示不全&#xff1b;有些没有定义&#xff0c;如百家姓 #include <Arduino.h> #include <…

Java经典框架之Spring

Java经典框架之Spring Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。 课程内容的介绍 1. Spring简介 2.…

HA启动Advanced SSH Web Terminal 提示附加组件似乎尚未准备就绪,它可能仍在启动。是否要再试一次?

环境&#xff1a; Home Assistant OS11.1 Advanced SSH & Web Terminal 17.0 问题描述&#xff1a; HA安装好SSH加载项&#xff0c;启动Advanced SSH & Web Terminal 提示附加组件似乎尚未准备就绪&#xff0c;它可能仍在启动。是否要再试一次&#xff1f; 解决方案…

.NET中的Swagger使用

目录 前言 一、Swagger是什么&#xff1f; 二、如何Swagger文档说明的信息 1.在AddSwaggerGen方法中写入文档信息 2.运行效果 二、文档UI界面标题、路由设置 1.在中间件UseSwaggerUI方法中配置 三、文档UI界面添加接口注释 1.在 .csproj中配置 2.在AddSwaggerGen方法中配置Incl…

Apache Spark简介与历史发展

在当今信息爆炸的时代&#xff0c;大数据处理已成为了现实。企业和组织需要处理海量数据来获得有用的信息和见解。Apache Spark作为一个开源的大数据处理框架&#xff0c;已经在大数据领域占据了重要地位。 Apache Spark简介 Apache Spark是一个用于大规模数据处理的快速、通…

新版IDEA中Git的使用(一)

说明&#xff1a;本文介绍如何在新版IDEA中使用Git 创建项目 首先&#xff0c;在GitLab里面创建一个项目&#xff08;git_demo&#xff09;&#xff0c;克隆到桌面上。 然后在IDEA中创建一个项目&#xff0c;项目路径放在这个Git文件夹里面。 Git界面 当前分支&Commit …

Qt/QML编程学习之心得:在QML中调用fileDialog(十六)

Qt中有一些内置的对话框dialog,比如 在QWidget工程中使用比较容易,比如 #include <QFileDialog>fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)")); 那么在QM…

word2003 open word2007+

Win 7 C:\Documents and Settings\Administrator\Application Data\Microsoft\Templates 还是不行&#xff0c;重装office2003吧&#xff0c;再安装转换插件&#xff0c;但是再高版本好像没转换工具

由正规表达式构造DFA,以及DFA的相关化简

目录 1.由正规式到DFA 首先讲如何从正规式到NFA 如何从NFA到DFA 2.DFA的化简 3.DFA和NFA的区别 1.由正规式到DFA 正规式--->NFA---->DFA 首先讲如何从正规式到NFA 转换规则: 例题1&#xff1a;这里圆圈里面的命名是随意的&#xff0c;只要能区别开就可以了 如何…

助力打造清洁环境,基于YOLOv4开发构建公共场景下垃圾堆放垃圾桶溢出检测识别系统

公共社区环境生活垃圾基本上是我们每个人每天几乎都无法避免的一个问题&#xff0c;公共环境下垃圾投放点都会有固定的值班时间&#xff0c;但是考虑到实际扔垃圾的无规律性&#xff0c;往往会出现在无人值守的时段内垃圾堆放垃圾桶溢出等问题&#xff0c;有些容易扩散的垃圾比…

【UML】第12篇 序列图(1/2)——基本概念和构成

目录 一、什么是序列图&#xff08;Sequence Diagram&#xff09; 1.1 定义 1.2 主要用途 1.3 序列图和BPMN的区别和联系 二、序列图的构成 2.1 对象 2.2 生命线 2.3 消息 2.4 激活 序列图&#xff0c;是我个人认为的用处最多的一种图。产品和研发的同学&#xff0c;都…

向量投影:如何将一个向量投影到矩阵的行向量生成子空间?

向量投影&#xff1a;如何将一个向量投影到矩阵的行向量生成子空间&#xff1f; 前言 本问题是在学习Rosen梯度投影优化方法的时候遇到的问题&#xff0c;主要是对于正交投影矩阵(NT(NNT)-1N)的不理解&#xff0c;因此经过查阅资料&#xff0c;学习了关于向量投影的知识&…

【Datawhale x 财务学习笔记】用智谱清言的代码沙盒进行分析

体验网址 智谱清言&#xff1a;https://chatglm.cn/ prompt 帮我分析一下这个excel文件&#xff0c;从财务角度给出利润情况&#xff0c;并给出优化建议体验结果 首先&#xff0c;我将查看上传的Excel文件的内容&#xff0c;以便了解其结构和包含的数据。然后&#xff0c;我…

相机内参标定理论篇------张正友标定法

一、为什么做相机标定&#xff1f; 标定是为了得到相机坐标系下的点和图像像素点的映射关系&#xff0c;为摄影几何、计算机视觉等应用做准备。 二、为什么需要张正友标定法&#xff1f; 张正友标定法使手工标定相机成为可能&#xff0c;使相机标定不再需要精密的设备帮助。…