Shell 编程快速入门 之 数学计算和函数基础

8c24851c4f9c4f6dbe0de1a3181800f5.png

目录

1. 求两数之和

整数之和

浮点数之和 

2. 计算1-100的和

for...in

C风格for循环

while...do

until...do

while和until的区别

关系运算符

break与continue的区别 

3. shell函数基础知识

函数定义 

函数名

函数体

参数

返回值

return返回值的含义

return与echo返回值的区别

4. 自定义库函数

定义库函数

调用库函数

执行结果

5. 递归函数

递归法实现阶乘函数

改用循环实现


1. 求两数之和

整数之和

shell程序的数字类型只有整数类型一种,并不支持浮点数。如:

hann@HannYang:~$ cat sum.sh
#!/bin/bash

# 读取第一个数
echo "请输入第一个数:"
read a

# 读取第二个数
echo "请输入第二个数:"
read b

# 计算两个数的和
sum=$(( a + b ))

# 输出结果
echo "这两个数的和为:$sum"
hann@HannYang:~$ bash sum.sh
请输入第一个数:
5
请输入第二个数:
3
这两个数的和为:8
hann@HannYang:~$

浮点数之和 

在shell编程中,浮点数只能被用作字符串来操作,脚本语法本身不提供浮点数的操作方法,但可以调用bc, awk等外部命令来计算并返回结果。如:

hann@HannYang:~$ cat sum2.sh
#!/bin/bash

num1=3.14
num2=2.72

# 计算和
sum=$(echo "$num1 + $num2" | bc)
echo "$num1 + $num2 = $sum"

sum=$(echo $num1 $num2 | awk '{print $1+$2}')
echo "$num1 + $num2 = $sum"
hann@HannYang:~$ bash sum2.sh
3.14 + 2.72 = 5.86
3.14 + 2.72 = 5.86

2. 计算1-100的和

用1~100累和的例子,示例循环结构的各种语句的写法:

for...in

hann@HannYang:~$ sum=0;for i in {1..100};do let sum+=i;done;echo $sum

C风格for循环

hann@HannYang:~$ sum=0;for ((i=1; i<=100; i++));do let sum+=i;done;echo $sum

while...do

sum=0  # 初始化变量sum为0
i=1  # 初始化计数器i为1
while [ $i -le 100 ]; do  # 当计数器i小于等于100时执行循环体
    let sum+=i  # 将当前整数累加到sum中
    i=$((i+1))  # 计数器自增1
done  # 结束循环
echo $sum  # 打印出变量sum的值

until...do

sum=0  # 初始化变量sum为0
i=1  # 初始化计数器i为1
until [ $i -gt 100 ]; do  # 当计数器i大于100时执行循环体
    let sum+=i  # 将当前整数累加到sum中
    i=$((i+1))  # 计数器自增1
done  # 结束循环
echo $sum  # 打印出变量sum的值

while和until的区别

while循环是当条件测试为真时执行,为假时退出循环
until循环是当条件测试为假时执行,为真时退出循环

while A; do 等价于 until not A; do
until A; do 等价于 while not A; do

while [ ! $i -gt 100 ]; do  <==> until [ $i -gt 100 ]; do
until [ ! $i -le 100 ]; do  <==> while [ $i -le 100 ]; do

关系运算符

-eq    equal 即 ==,检测两个数是否相等,相等返回 true。
-ne    not equal 即 !=,检测两个数是否不相等,不相等返回 true。
-gt    great than 即 >,检测左边的数是否大于右边的,如果是,则返回 true。
-lt     less than 即 <,检测左边的数是否小于右边的,如果是,则返回 true。
-ge    great equal 即>=,检测左边的数是否大于等于右边的,如果是,则返回 true。
-le    less equal,即<=,检测左边的数是否小于等于右边的,如果是,则返回 true。

break与continue的区别 

break语句用于退出本层循环,当执行到break会立即跳出当前循环,执行后续代码。
在多层嵌套循环中,break只会跳出最近的一层循环。

continue语句用于结束本次循环,跳过本次循环中剩余的代码,直接进入下一次循环。
在多层嵌套循环中,continue只会跳过最近的一层循环。

两种语句的基本用法与其它语言的基本一样,不另举例说明。

3. shell函数基础知识

函数定义 

函数名

Shell函数用关键字 function 声明,跟在后面的 name 即函数名。声明后就用"函数名 [参数]"来调用函数。function 非必须,也能用函数名加一对括号 name() { ... } 来声明定义函数。

函数体

函数名后的 { Commands; } 即函数体,是实现函数功能的主体。

参数

Shell函数可以通过参数接收输入的值。在函数定义时,可以在括号中指定参数列表。参数可以在函数体中使用,也可以通过特殊变量$#获取函数的参数个数,通过特殊变量$@获取所有的参数。

返回值

Shell函数可以有一个返回值,可以使用return语句返回一个值。返回值的范围是0到255之间,0表示成功,非零值表示错误。如果函数中没有return语句,或者使用exit命令退出函数,则函数的返回值为退出命令的返回值。

如一个计算2数之和的函数:

#!/bin/bash
function add() {
  local a=$1
  local b=$2
  local res=$((a + b))
  return $res
}

add 3 5
result=$?
echo "The result is: $result"

return返回值的含义

最后结果是从$?获取的,其实$?与其它语言中函数返回值是有区别 ,$? 本质上是返回上一条命令的退出状态,并且只是0~255间的整数,也就是最多返回256种状态。

除了$?还有另外4个特殊的变量,它们分别表示以下含义:

  • $$:表示当前Shell进程的进程ID(PID)。
  • $#:表示传递给脚本或函数的参数个数。
  • $@:表示以空格分隔的所有参数,将所有参数视为单个字符串。
  • $*:表示所有参数作为单独的字符串展开,每个参数之间用一个空格分隔。

例程:

hann@HannYang:~$ more sum3.sh
#!/bin/bash

function special_vars() {
  echo "Current PID \$: $$"
  echo "Number of arguments #: $#"
  echo "All arguments (as a single string) @: $@"
  echo "All arguments separated by spaces *: $*"
  echo
  return $(($1+$2+$3))
}

special_vars 1 2 3 4 5
echo "? = "$?
echo "\$ = "$$
echo "# = "$#
echo "@ = "$@
echo "* = "$*
hann@HannYang:~$ bash sum3.sh
Current PID $: 1679
Number of arguments #: 5
All arguments (as a single string) @: 1 2 3 4 5
All arguments separated by spaces *: 1 2 3 4 5

? = 6
$ = 1679
# = 0
@ =
* =

$?只能函数执行后调用,$#,$@,$*只能在函数内部调用,$$则在函数内外都能调用。

return与echo返回值的区别

为了显示两者的不通,echo后加了“sum=”,而return只能返回整数0~255。

例程:

#!/bin/bash
function add() {
  local a=$1
  local b=$2
  local res=$((a + b))
  echo sum=$res
  return $res
}

Result=$(add 100 155)
echo "The result is: $?"
echo "The result is: $Result"

Result=$(add 100 156)
echo "The result is: $?"
echo "The result is: $Result"

Result=$(add 155 358)
echo "The result is: $?"
echo "The result is: $Result"

echo "The result is: $(( (155+358)%256 ))"

输出:

The result is: 255
The result is: sum=255
The result is: 0
The result is: sum=256
The result is: 1
The result is: sum=513
The result is: 1

注意:

return 返回表达式的值,如溢出范围可以认为是 表达式与256相余的结果。

所以shell函多用echo来返回一个字串结果$res再进行调用,而return一般不会作函数值返回语句,它的真实用途是来返回程序运行状态的,比如:

例1:

hann@HannYang:~$ cat test.sh
#!/bin/bash

function filecount {
    # 检查目录是否存在
    if [ -d "$1" ]; then
        # 目录存在,计算文件数
        echo $(ls -l "$1" | grep "^-" | wc -l)
        return 1
    else
        # 目录不存在,返回0
        return 0
    fi
}

dir="$1"
count=$(filecount $dir)

if [ $? = 1 ]
then
    echo "Dir $dir exists,files:$count"
else
    echo "Dir $dir does'nt exist."
fi

dir="$2"
count=$(filecount $dir)

if [ $? = 0 ]
then
    echo "Dir $dir does'nt exist."
else
    echo "Dir $dir exists,files:$count"
fi
hann@HannYang:~$ bash test.sh rust golang
Dir rust exists,files:4
Dir golang does'nt exist.

例2:

hann@HannYang:~$ cat chkpid.sh
checkpid()
{
   #定义本地变量i
    local i

   #使用for循环遍历传递给此函数的所有参数
    for i in $*
    do
       #如果目录/proc/$i存在,则执行此函数返回0
       #在一般的Linux系统中,如果进程正在运行,则在/proc目录下会存在一个以进程号命名的子目录
       [ -d "/proc/$i" ] && return 0
    done

    #返回1
    return 1
}

#调用函数checkpid
checkpid $1 $2 $3

if [ $? = 0 ]
then
    echo "The one of them is running."
else
    echo "These PIDS are not running!"
fi
hann@HannYang:~$ bash chkpid.sh 866
The one of them is running.
hann@HannYang:~$ bash chkpid.sh 866 867 1882
The one of them is running.
hann@HannYang:~$ bash chkpid.sh 1882
These PIDS are not running!
hann@HannYang:~$ bash chkpid.sh 868 1882
These PIDS are not running!

可变参数函数

"$@"的应用: in $@表示遍历所有参数组成的“可迭代数组”。

示例:

#!/bin/bash

# 定义可变参数的函数
function sum4() {
  local sum=0
  for arg in "$@"
  do
    sum=$((sum + arg))
  done
  echo "The sum is: $sum"
}

# 调用函数并传递参数
sum4 10 20 30 50
sum4 1 2 3 4 5 6

输出:

The sum is: 110
The sum is: 21 

4. 自定义库函数

定义库函数

例:写一个函数库,如命名为 math_fun.sh 

function add
{
    echo "`expr $1 + $2`"
}

function sub
{
    echo "`expr $1 - $2`"
}

function mul
{
    echo "`expr $1 \* $2`"
}

function div
{
    if [ $2 = 0 ]; then
        return 0
    else
        echo "`expr $1 / $2`"
        return 1
    fi
}

调用库函数

在调用库文件的函数时,使用点符号“ . ” + 库函数文件名(指明文件的绝对路径、相对路径都行)进行调用。如 test_fun.sh :

#!/bin/bash
. math_fun.sh

add 10 20

sub 90 100

mul 5 6

div 100 25

div 0 100

div 100 0
if [ $? = 0 ];then
    echo "Error: divide by zero."
fi

执行结果

hann@HannYang:~$ bash test_fun.sh
30
-10
30
4
0
Error: divide by zero.

5. 递归函数

递归函数是一种在程序中调用自身的函数。在 Shell 编程中,也能使用递归函数来解决一些问题,例如计算阶乘、斐波那契数列等。

递归函数的实现需要满足以下两个条件:

  1. 函数必须有一个终止条件,否则会无限循环下去。
  2. 函数必须能够将问题分解成更小的问题,并且能够通过调用自身来解决这些小问题。

递归法实现阶乘函数

#!/bin/bash

factorial() {
    if [ $1 -le 1 ]
    then
        echo 1
    else
        echo $(( $1 * $(factorial $(( $1 - 1 ))) ))
    fi
}

read -p "请输入一个整数:" num
result=$(factorial $num)
echo "$num 的阶乘为 $result"

改用循环实现

#!/bin/bash

factorial() {
    local result=1
    for ((i=1; i<=$1; i++))
    do
        result=$((result * i))
    done
    echo $result
}

read -p "请输入一个整数:" num
result=$(factorial $num)
echo "$num 的阶乘为 $result"

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Ubuntu】从Graylog到Grafana Loki:构建更强大的网络设备管理和监控系统

在将Graylog部署到生产环境时&#xff0c;我们遇到了一些问题&#xff0c;其中最主要的是无法安装MongoDB并且无法随时重启机器去修改BIOS设置来修复问题 【WARNING: MongoDB 5.0 requires a CPU with AVX support, and your current system does not appear to have that! 】。…

AI 绘画Stable Diffusion 研究(十一)sd图生图功能详解-美女换装

免责声明: 本案例所用安装包免费提供&#xff0c;无任何盈利目的。 大家好&#xff0c;我是风雨无阻。 为了让大家更直观的了解图生图功能&#xff0c;明白图生图功能到底是干嘛的&#xff0c;能做什么事情&#xff1f;今天我们继续介绍图生图的实用案例-美女换装的制作。 对于…

第6天----【位运算进阶之-----位与()】七夕特别版

今天我们来学习C语言的位与。 ❤️C语言的位与&#xff08;&&#xff09;操作是一种按位运算符&#xff0c;用于对两个操作数的每个对应位执行逻辑与操作。它的操作规则如下&#xff1a; 如果两个操作数的对应位都为1&#xff0c;则结果的对应位也为1。&#xff08;全1才…

pdf怎么转换成图片?用这几种简单方法搞定

pdf怎么转换成图片&#xff1f;PDF作为一种通用的文档格式&#xff0c;广泛应用于各个领域。然而&#xff0c;在某些情况下&#xff0c;我们可能需要将PDF文件转换成图片格式&#xff0c;以便更方便地在网页、社交媒体或演示中使用。下面就给大家介绍三种简单而高效的方法来实现…

基于springboot灾区物资管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

【Leetcode】移动零

移动零 题目描述算法描述编程代码 链接: 移动零 题目描述 算法描述 编程代码 class Solution { public:void moveZeroes(vector<int>& nums) {//题目要求不可以复制数组&#xff0c;开辟额外空间int dest -1,curr 0;for(;curr < nums.size();curr){if(nums[cu…

linux中互斥锁,自旋锁,条件变量,信号量,与freeRTOS中的消息队列,信号量,互斥量,事件的区别

RTOS 对于目前主流的RTOS的任务&#xff0c;大部分都属于并发的线程。 因为MCU上的资源每个任务都是共享的&#xff0c;可以认为是单进程多线程模型。 【freertos】003-任务基础知识 在没有操作系统的时候两个应用程序进行消息传递一般使用全局变量的方式&#xff0c;但是如…

jenkins 是什么?

一、jenkins 是什么&#xff1f; Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具&#xff0c;起源于Hudson&#xff0c;主要用于持续、自动的构建/测试软件项目、监控外部任务的运行。Jenkins用Java语言编写&#xff0c;可在Tomcat等流行的servlet容器中运行&#…

GraphScope,开源图数据分析引擎的领航者

文章首发地址 GraphScope是一个开源的大规模图数据分析引擎&#xff0c;由Aliyun、阿里巴巴集团和华为公司共同开发。GraphScope旨在为大规模图数据处理和分析提供高性能、高效率的解决方案。 Github地址&#xff1a; https://github.com/alibaba/GraphScope GraphScope 的重…

redis7高级篇3 数据量亿级别的统计分析(hyperloglog,bitmap,geo)

一 亿级别统计分类 1.1 统计分类 1.聚合统计&#xff1a;统计多个集合聚合的结果&#xff0c;也就是多个集合之间交并差的统计。 2.排序统计&#xff1a;在需要展示最新列表&#xff0c;排行榜等场景时&#xff0c;如果数据更新频繁或者需要分页时&#xff0c;建议使用zset12…

适合国内用户的五款ChatGPT插件

众所周知使用ChatGPT3.5需要使用魔法且不稳定&#xff0c;订阅ChatGPT4.0每月需要支付20美元&#xff0c;并且使用次数有限制。对于那些不想每年花费240美元&#xff08;超过1500元人民币&#xff09;来使用GPT4.0的朋友们来说&#xff0c;还有别的办法吗&#xff1f; 答案…

安防视频能力平台EasyNVR视频汇聚平台关闭匿名登陆的问题的解决步骤

EasyNVR是基于RTSP/Onvif协议的安防视频能力平台&#xff0c;它可实现设备接入、实时直播、录像、检索与回放、存储、视频分发等视频能力服务&#xff0c;可覆盖全终端平台&#xff08;pc、手机、平板等终端&#xff09;&#xff0c;在智慧工厂、智慧工地、智慧社区、智慧校园等…

pbootcms系统安全防护设置大全

PbootCMS系统简介 PbootCMS是全新内核且永久开源免费的PHP企业网站开发建设管理系统&#xff0c;是一套高效、简洁、 强悍的可免费商用的PHP CMS源码&#xff0c;能够满足各类企业网站开发建设的需要。系统采用简单到想哭的模板标签&#xff0c;只要懂HTML就可快速开发企业网站…

[JavaWeb]【八】web后端开发-Mybatis

目录 一 介绍 二 Mybatis的入门 2.1 快速入门 2.1.1 准备SpringBoot工程 2.1.2 创建数据库mybatis以及对应库表user 2.1.3 创建User实体类 2.1.4 配置application.properties数据库连接信息 2.1.5 编写sql语句&#xff08;注解方式&#xff09; 2.1.6 测试运行 2.1.7 配…

无涯教程-Perl - unshift函数

描述 此函数按顺序将LIST中的元素放在ARRAY的开头。这与shift()相反。 语法 以下是此函数的简单语法- unshift ARRAY, LIST返回值 此函数返回ARRAY中新元素的数量。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl -warray ( 1, 2, 3, 4);print "Value of a…

容斥原理 博弈论(多种Nim游戏解法)

目录 容斥原理容斥原理的简介能被整除的数&#xff08;典型例题&#xff09;实现思路代码实现扩展&#xff1a;用DPS实现 博弈论博弈论中的相关性质博弈论的相关结论先手必败必胜的证明Nim游戏&#xff08;典型例题&#xff09;代码实现 台阶-Nim游戏&#xff08;典型例题&…

16.遍历二叉树,线索二叉树

目录 一. 遍历二叉树 &#xff08;1&#xff09;三种遍历方式 &#xff08;2&#xff09;递归遍历算法 &#xff08;3&#xff09;非递归遍历算法 &#xff08;4&#xff09;层次遍历算法 二. 基于递归遍历算法的二叉树有关算法 &#xff08;1&#xff09;二叉树的建立 …

解决elementUI打包上线后icon图标偶尔乱码的问题

解决vue-elementUI打包后icon图标偶尔乱码的问题 一、背景二、现象三、原因四、处理方法方式1&#xff1a;使用css-unicode-loader方式2&#xff1a;升高 sass版本到1.39.0方式3&#xff1a;替换element-ui的样式文件方式4&#xff1a;更换打包压缩方式知识扩展&#xff1a;方式…

苹果手机桌面APP带云图标有个箭头,过一段时间经常要下载才能使用APP

环境&#xff1a; IPhone 11 IOS13.0 问题描述&#xff1a; 苹果手机桌面APP带云图标有个箭头&#xff0c;过一段时间经常要下载才能使用APP 解决方案&#xff1a; 1.打开设置&#xff0c;往下找到iTunes Store与App Store 2.找到下面卸载未使用的APP 关闭按钮

pdf格式怎么编辑?了解这种编辑方法就可以了

pdf格式怎么编辑&#xff1f;PDF作为一种通用的文档格式&#xff0c;以其跨平台、保真排版等优势在各个领域得到广泛应用。然而&#xff0c;对于许多人来说&#xff0c;PDF文件一直以来都被视为“静态”文件&#xff0c;不易编辑。但现在&#xff0c;有很多编辑器可以帮助我们进…