安远网站制作,怎么做粉丝福利购网站,房产如何做网站,网站开发图片压缩上传报酬shell脚本实战学习笔记#1
脚本编写场景需求#xff1a; 编写一个比较数据大小的shell脚本#xff0c;要求判断用户只能输入两位数字#xff0c;不能是字符或其他特殊字符#xff1b;并且在shell脚本中需要用到函数来控制执行顺序。
知识点#xff1a;shell函数#xff…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大于判断值$number2elif [ $number1 -eq $number2 ];then echo $number1等于判断值$number2elseecho $number1小于判断值$number2fi
}#主函数运行部分定义执行哪些函数以及执行的先后顺序
main(){check_input $check_Numberjudge_number
}
#程序运行
main $ 需求分析
首先要让用户执行脚本时传入两个参数因此给定$1 $2两个变量需求表明只能输入两个数字因此判断逻辑有两层判断变量个数为2个判断输入内容是否为数字。若满足两个判断条件需要做数字比较的动作这是脚本的核心需求。
实现过程
#!/bin/bash# 定义变量
number10# 条件判断
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大于判断值$number2elif [ $number1 -eq $number2 ]; then echo $number1等于判断值$number2elseecho $number1小于判断值$number2fi
}# 主函数运行部分定义执行哪些函数以及执行的先后顺序
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大于判断值$number2elif [ $number1 -eq $number2 ]; then echo $number1等于判断值$number2elseecho $number1小于判断值$number2fi
}# 主函数运行部分定义执行哪些函数以及执行的先后顺序
main() {check_input $check_Numberjudge_number
}# 程序运行
main $
以上内容就是基本实现一个数据比较的shell脚本需求同时也确保了脚本的逻辑更加合理且健壮。
以上便是本次实战操作的所有过程了。
感谢您在百忙之中花费时间阅读本篇文章期望对您的体能提升有所收获