百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Bash技巧:介绍算术扩展进行算术运算和比较判断的用法

nanshan 2024-11-10 10:14 25 浏览 0 评论


在 Linux bash shell 中,算术扩展(arithmetic expansion)可以获取算术表达式的运算结果。
还可以进行加减乘除运算、比较大小、比较是否相等、进行与或非运算,等等。

查看 man bash 的说明如下:

Arithmetic expansion allows the evaluation of an arithmetic expression and the substitution of the result. The format for arithmetic expansion is:

       $((expression))

The old format $[expression] is deprecated and will be removed in upcoming versions of bash.
The expression is treated as if it were within double quotes, but a double quote inside the parentheses is not treated specially. All tokens in the expression undergo parameter and variable expansion, command substitution, and quote removal.
The result is treated as the arithmetic expression to be evaluated. Arithmetic expansions may be nested.


The evaluation is performed according to the rules listed below under ARITHMETIC EVALUATION. If expression is invalid, bash prints a message indicating failure and no substitution occurs.

即,$((expression)) 算术扩展会按照 ARITHMETIC EVALUATION 描述的规则来评估 expression 算术表达式,并获取到该表达式的值。

算术表达式里面默认进行变量扩展、命令替换、移除引号。
由于默认进行变量扩展,可以直接用变量名来获取变量值,不需要在变量名前面加 $ 符号。

如果只是要评估算术表达式,不需要获取算术表达式的值,写为 ((expression)) 即可。
查看 man bash 对 ((expression)) 复合命令的说明如下:

((expression))
The expression is evaluated according to the rules described below under ARITHMETIC EVALUATION.
If the value of the expression is non-zero, the return status is 0; otherwise the return status is 1.
This is exactly equivalent to let "expression".

即,写为 ((expression)) 这个形式,也会按照 ARITHMETIC EVALUATION 描述的规则来评估 expression 算术表达式,只是获取不到该表达式的值。
它等价于 let "expression" 语句。

具体的 ARITHMETIC EVALUATION 规则可以查看 man bash 的说明,里面的关键点如下:

The operators and their precedence, associativity, and values are the same as in the C language.

即,在 ((expression)) 表达式中,所使用的运算符、运算符优先级、运算符结合规则跟 C 语言一致。
对于熟悉 C 语言的人来说,方便使用。

具体举例说明如下:

$ number=1

$ number+=5

$ echo $number

15

$ number=$((number + 3))

$ echo $number

18

$ ((number += 3))

$ echo $number

21

可以看到,先将 number 赋值为 1,然后执行 number+=5 语句。
但是打印 number 变量值,结果是 15,而不是 6。
即,直接写为 number+=5 的形式,是字符串拼接,而不是进行算术运算。

number=$((number + 3)) 命令使用算术扩展,会获取到 number 变量值加上 3 之后的值,并赋值给 number 变量值,是 18。
这个表达式进行了算术运算。

((number += 3)) 命令没有使用算术扩展,只是处理算术表达式。
通过算术表达式的 += 赋值操作符,把 number 变量值加上 3,并赋值给 number 变量。
这个写法跟 number=$((number + 3)) 命令的效果相同。

在算术表达式内,直接通过 number 变量名就可以获取变量值,不需要写为 $number 的形式。

总的来说,在 bash 中,要进行算术表达式运算,需要使用特定的写法、或者在一些支持算术运算的命令中使用。
直接写为算术表达式自身,并不能进行算术运算。

使用算法表达式进行比较判断

在 bash 的 算法表达式中,支持 <=、>=<、>、==、!= 这 6 个常见的运算符,可用于进行比较判断。

假设有一个 arth_check.sh 脚本,内容如下:

(不好意思,近期网页版文章的代码块排版错乱,后台咨询确认网页版不支持。下面用四个 ‘----’ 代替四个空格来进行缩进和隔行显示。后面的代码块会类似处理。如果需要复制代码到本地验证,麻烦以四个 ‘----’为单位,替换成四个空格。非常抱歉。)

#!/bin/bash

if [ $# -ne 2 ]; then

----echo "Usage: $0 number1 number2"

----exit 1

fi

----

number1="$1"

number2="$2"

----

if ((number1 > number2)); then

----echo "$number1 > $number2"

elif ((number1 < number2)); then

----echo "$number1 < $number2"

elif ((number1 == number2)); then

----echo "$number1 == $number2"

else

----echo "Should never be here."

fi

这个 arth_check.sh 脚本要求提供两个参数,然后用算术表达式比较这两个参数值的大小关系。

使用 if ((number1 > number2)) 语句进行比较判断,变量名和 (( 和 )) 之间可以不加空格,也不需要对 > 操作符进行转义。
如果使用 [ 命令来比较,则变量名和 [ 和 ] 之间必须加空格,还要用 \ 对 > 操作符进行转义。
也就是写为 if [ number1 \> number2 ]
可以看到,使用 if ((number1 > number2)) 这个写法更加简单方便,可以避免不加空格、或者不转义带来的异常。

执行 arth_check.sh 脚本,结果如下:

$ ./arth_check.sh 1 2

1 < 2

$ ./arth_check.sh 2 1

2 > 1

$ ./arth_check.sh 2 2

2 == 2

相关推荐

Centos7虚拟机安装及网络配置(二)

#二、centos7的网络配置-Nat模式NAT模式也是VMware创建虚拟机的默认网络连接模式。使用NAT模式网络连接时,VMware会在主机上建立单独的专用网络,用以在主机和虚拟机之间相互通信。虚...

网络分析shell脚本(实时流量+连接统计)

介绍一个强大的分析网络的shell脚本,此脚本是从EZHTTP拆分出来的,觉得有必要单独介绍下。脚本运行效果截图:此脚本包含的功能有:1、实时监控任意网卡的流量2、统计10秒内平均流量3、统计每个端口...

Centos之Could not retrieve mirrorlist解决方案

Centos之Couldnotretrievemirrorlist解决方案:vi/etc/sysconfig/network-scripts/ifcfg-你的网卡名字修改:ONBOOT=ye...

一文掌握!VirtualBox 中 Rock9.x(Linux)网络配置全攻略

一、前言记得我有一篇文章《必看!VirtualBox中Centos7(Linux)网络配置全攻略》讲的非常明细,但是因为CentOS已经停止维护了,可能很多人都不想继续学CentOS,我也是一样,...

CentOS 6.0 设置IP地址、网关、DNS

在做任何操作之前先备份原文件,我们约定备份文件的名称为:源文件名称+bak,例如原文件名称为:centos.txt那么备份文件名称为:centos.txtbak引言:linux的网卡IP地址是存放在文...

Linux CentOS 基础操作(centos怎么操作)

简介:养成学习Linux的好习惯,第一是多查看manpage(manual)等帮助文档和利用好Tab键;第二是掌握好一些快捷键,比如ctrl+c(停止当前进程),ctrl+r(查看命令历史)...

Linux抓包王者技能!这条命令直接封神,教你精准定位网络问题

在网络故障排查和性能调优中,抓包是一项必不可少的技能。对于Linux环境下的网络工程师和运维人员来说,掌握高效抓包方法至关重要。而要说“抓包界的王炸”,那非tcpdump莫属!今天,我们不仅要介绍...

「干货」如何在 Linux 上划分VLAN?

在某些场景中,我们希望在Linux服务器(CentOS/RHEL)上的同一网卡分配来自不同VLAN的多个ip。这可以通过启用VLAN标记接口来实现,但要实现这一点,首先必须确保交换机上添加多个vl...

CentOS 8 网络配置实战教程:静态IP、路由与DNS设置

一、配置前准备1.查看当前网络信息#查看所有网络接口nmclidevicestatus#查看指定网卡信息(假设网卡名为ens192)ipaddrshowens192#查看路由...

Debian10.7修改网络配置(debian怎么配置网络)

简介:关于Debian获取IP地址的方法主要有两种,动态获取和静态设置。在配置网络之前先要知道Debian的网卡名称是什么,Debian可通过命令#ipa查看网卡名称。本文主要通过介绍Debian...

巧用SSH转发功能深入穿透内网(ssh转发udp)

ssh能够提供客户端到服务端的加密传输,当http、ftp等协议被防火墙所拦截时,可以考虑使用SSH的端口转发功能,将其它TCP端口的网络数据通过SSH连接来转发。转发方式一共有三种,分别是:动态转发...

CentOS Linux 7 的IP地址配置(centos7.4配置ip地址)

前段时间有位朋友,在一台PC机上安装了CentOSLinux7系统,因为要接入局域网,需要配置IP地址和默认网关信息。于是参照一本Linux教程上编辑网卡配置信息的方法,输入:vim/etc/s...

教你如何在 Linux 上划分VLAN(linux怎么分区详解)

在某些场景中,我们希望在Linux服务器(CentOS/RHEL)上的同一网卡分配来自不同VLAN的多个ip。这可以通过启用VLAN标记接口来实现,但要实现这一点,首先必须确保交换机上添加多个vl...

打通数据高速公路:如何在 CentOS 上使用 Thunderbolt 3 和 4

Thunderbolt3与4是现代高速外设连接的代表,带来了40Gbps的惊人带宽,支持数据、视频、音频与供电的“四合一”功能,尤其在专业视频编辑、科研计算、虚拟化扩展等领域具有巨大价值...

VMware 虚拟机 CentOS7 桥接模式静态 IP 配置全攻略

虚拟机桥接模式原理配置成桥接网络连接模式的虚拟机就当作主机所在以太网的一部分,虚拟系统和宿主机器的关系,就像连接在同一个Hub上的两台电脑,可以像主机一样可以访问以太网中的所有共享资源和网络连接,可以...

取消回复欢迎 发表评论: