热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Shell中的数值运算

Shell中的数值运算案例1:Shell中的数值运算案例2:条件测试操作案例3:使用if选择结构1案例1:Shell中的数值运算1.1问题本案例要求熟悉LinuxShell环境的特

                                                                     Shell中的数值运算

案例1Shell中的数值运算

案例2:条件测试操作

案例3:使用if选择结构

1案例1Shell中的数值运算

1.1问题

本案例要求熟悉Linux Shell环境的特点,主要练习以下操作:

使用expr$[]let等整数运算工具:定义变量X=1234,然后计算X78的四则运算及求模结果

使用bc实现小数运算操作:以交互方式计算12.3456.78的四则运算结果,另外再以非交互方式重复上述计算,最多显示4位小数

1.2步骤

实现此案例需要按照如下步骤进行。

步骤一:整数运算工具

1)使用expr命令

乘法操作应采用\*转义,避免被作为Shell通配符;参与运算的整数值与运算操作符之间需要以空格分开,引用变量时必须加$符号。

首先定义变量X=1234,然后分别计算与78的加减乘除和求模运算结果:

[root@svr5~]#X=1234//定义变量X

[root@svr5~]#expr $X+78//加法

1312

[root@svr5~]#expr $X-78//减法

1156

[root@svr5~]#expr $X\*78//乘法,操作符应添加\转义

96252

[root@svr5~]#expr $X/78//除法,仅保留整除结果

15

[root@svr5~]#expr $X%78//求模

64

2)使用$[]$(())表达式

乘法操作*无需转义,运算符两侧可以无空格;引用变量可省略$符号;计算结果替换表达式本身,可结合echo命令输出。

同样对于变量X=1234,分别计算与78的加减乘除和求模运算结果:

[root@svr5~]#X=1234

[root@svr5~]#echo $[X+78]

1312

[root@svr5~]#echo $[X-78]

1156

[root@svr5~]#echo $[X*78]

96252

[root@svr5~]#echo $[X/78]

15

[root@svr5~]#echo $[X%78]

64

3)使用let命令

expr$[]$(())方式只进行运算,并不会改变变量的值;而let命令可以直接对变量值做运算再保存新的值。因此变量X=1234,在执行let运算后的值会变更;另外,let运算操作并不显示结果,但是可以结合echo命令来查看:

[root@svr5~]#X=1234

[root@svr5~]#let y=X+22

[root@svr5~]#echo $y

1256

[root@svr5~]#let X++;echo $X #X++(X=X+1)

[root@svr5~]#let X--;echo $X #X--(X=X-1)

[root@svr5~]#let X+=78;echo $X #X+=78(X=X+78)

[root@svr5~]#let X-=78;echo $X #X-=78(X=X-78)

[root@svr5~]#let X*=78;echo $X #X*=78(X=X*78)

[root@svr5~]#let X/=78;echo $X #X/=78(X=X/78)

[root@svr5~]#let X%=78;echo $X #X%=78(X=X%79)

步骤二:小数运算工具

1bc交互式运算

先执行bc命令进入交互环境,然后再输入需要计算的表达式。以计算小数12.345.678的四则运算为例,相关操作如下:

[root@svr5~]#bc

bc 1.06.95

Copyright 1991-1994,1997,1998,2000,2004,2006 Free Software

Foundation,Inc.

This is free software with ABSOLUTELY NO WARRANTY.

For details type`warranty‘.

12.34+56.78//加法

69.12

12.34-56.78//减法

-44.44

12.34*56.78//乘法

700.66

12.34/56.78//除法

0

quit//退出交互计算器

[root@svr5~]#

2bc非交互式运算

将需要运算的表达式通过管道操作交给bc运算。注意,小数位的长度可采用scale=N限制,除此以外也受参与运算的数值的小数位影响。以计算小数12.345.678的四则运算为例,相关操作如下:

[root@svr5~]#echo ‘scale=4;12.34+5.678‘ | bc

18.018

[root@svr5~]#echo ‘scale=4;12.34-5.678‘ | bc

6.662

[root@svr5~]#echo ‘scale=4;12.34 * 5.678‘ | bc

70.0665

[root@svr5~]#echo ‘scale=4;12.34/5.678‘ | bc

2.1733


 案例2:条件测试操作

2.1问题

本案例要求参考PPT上的示例,分别练习以下条件测试操作:

字符串匹配

比较整数值的大小

识别文件/目录的状态

多个条件/操作的逻辑组合

2.2步骤

实现此案例需要按照如下步骤进行。

步骤一:条件测试的基本用法

1)语法格式

使用test表达式”或者[表达式]都可以,表达式两边至少要留一个空格。

条件测试操作本身不显示出任何信息。测试的条件是否成立主要体现在命令执行后的返回状态(即$?),所以可以在测试后查看变量$?的值来做出判断,或者结合&&||等逻辑操作显示出结果(或作其他操作)。

步骤二:字符串测试

1==比较两个字符串是否相同

检查当前用户是否为root

root用户执行时:

[root@svr5~]#[ $USER=="root" ]//测试

[root@svr5~]#echo $?//查看结果0为对,非0为错

当普通用户执行时:

[zengye@svr5~]$[ $USER=="root" ]

[zengye@svr5~]$echo $?

2!=比较两个字符串是否不相同

检查当前用户,如果不是root

当普通用户执行时:

[zengye@svr5~]$[ $USER!="root" ]

root用户执行时:

[root@svr5~]#[ $USER!="root" ]

3)一行执行多条命令的情况

#A&&B//仅当A命令执行成功,才执行B命令

#A||B//仅当A命令执行失败,才执行B命令

#A;B//执行A命令后执行B命令,两者没有逻辑关系

4)-z检查变量的值是否未设置(空值)

[root@svr5~]#var1="nb";var2=""

[root@svr5~]#[ -z "$var1" ] && echo "空值" || echo "非空值"

非空值

[root@svr5~]#[ -z $var2 ] && echo "空值" || echo "非空值"

空值//变量var2已设置,但无任何值,视为空

[root@svr5~]#[ !-z $var1 ]//测试var1是否为非空

步骤三:整数值比较

参与比较的必须是整数(可以调用变量),比较非整数值时会出错:

[root@svr5~]#A=20.4

[root@svr5~]#[ $A -gt 10 ] //不支持小数比较

-bash:[:20.4:integer expression expected

1-eq比较两个数是否相等。

[root@svr5~]#X=20//定义一个测试变量

[root@svr5~]#[ $X -eq 20 ] && echo "相等" || echo "不相等"

相等

[root@svr5~]#[ $X -eq 30 ] && echo "相等" || echo "不相等"

不相等

2-ne比较两个数是否不相等。

[root@svr5~]#X=20//定义一个测试变量

[root@svr5~]#[ $X -ne 20 ] && echo "不等于" || echo "等于"

等于

[root@svr5~]#[ $X -ne 30 ] && echo "不等于" || echo "等于"

不等于

3-gt比较前面的整数是否大于后面的整数。

[root@svr5~]#X=20//定义一个测试变量

[root@svr5~]#[ $X -gt 10 ] && echo "大于" || echo ""

大于

[root@svr5~]#[ $X -gt 20 ] && echo "大于" || echo ""

[root@svr5~]#[ $X -gt 30 ] && echo "大于" || echo ""

4-ge比较前面的整数是否大于或等于后面的整数。

[root@svr5~]#X=20//定义一个测试变量

[root@svr5~]#[ $X -ge 10 ] && echo "大于或等于" || echo ""

大于或等于

[root@svr5~]#[ $X -ge 20 ] && echo "大于或等于" || echo ""

大于或等于

[root@svr5~]#[ $X -ge 30 ] && echo "大于或等于" || echo""

5-lt比较前面的整数是否小于后面的整数。

[root@svr5~]#X=20//定义一个测试变量

[root@svr5~]#[ $X -lt 10 ] && echo "小于" || echo ""

[root@svr5~]#[ $X -lt 20 ] && echo "小于" || echo ""

[root@svr5~]# [ $X -lt 30 ] && echo "小于" || echo""

小于

6-le比较前面的整数是否小于或等于后面的整数。

[root@svr5~]#X=20//定义一个测试变量

[root@svr5~]#[ $X -le 10 ] && echo "小于或等于" || echo ""

[root@svr5~]#[ $X -le 20 ] && echo "小于或等于" || echo ""

小于或等于

[root@svr5~]#[ $X -le 30 ] && echo "小于或等于" || echo""

小于或等于

7)提取当前登录的用户数,比较是否超过5

[root@svr5~]#who | wc -l//确认已登录的用户数

4

[root@svr5~]#N=$( who | wc -l )//赋值给变量N

[root@svr5~]#[ $N -gt 5 ] && echo "超过了" || echo "没超过"

没超过

上述赋值给变量N及与5比较的操作,可以简化为如下形式:

[root@svr5~]#[ $(who | wc -l ) -gt 5 ] && echo "超过了" || echo "没超过"

没超过

步骤四:识别文件/目录的状态

1-e判断对象是否存在(不管是目录还是文件)

[root@svr5~]#[ -e "/usr/" ] && echo "存在" || echo "不存在"

存在

[root@svr5~]# [ -e "/etc/fstab" ] && echo "存在" || echo "不存在"

存在

[root@svr5~]#[ -e "/home/nooby" ] && echo "存在" || echo "不存在"

不存在

2-d判断对象是否为目录(存在且是目录)

[root@svr5~]#[ -d "/usr/" ] && echo "是目录" || echo "不是目录"

是目录

[root@svr5~]#[ -d "/etc/fstab" ] && echo "是目录" || echo "不是目录"

不是目录

[root@svr5~]#[ -d "/home/nooby" ] && echo "是目录" || echo "不是目录"

不是目录

3-f判断对象是否为文件(存在且是文件)

[root@svr5~]#[ -f "/usr/" ] && echo "是文件" | |echo "不是文件"

不是文件

[root@svr5~]#[-f "/etc/fstab" ] && echo "是文件" || echo "不是文件"

是文件

[root@svr5~]#[ -f "/home/nooby" ] && echo "是文件" || echo "不是文件"

不是文件

4-r判断对象是否可读

此测试对root用户无效,无论文件是否设置r权限,root都可读:

[root@svr5~]#cp /etc/hosts /tmp/test.txt//复制一个文件做测试

[root@svr5~]#chmod -r /tmp/test.txt//去掉所有的r权限

[root@svr5~]#[ -r "/tmp/test.txt" ] && echo "可读" || echo "不可读"

可读//root测试结果仍然可读

切换为普通用户,再执行相同的测试,结果变为“不可读”:

[zengye@svr5~]$[ -r "/tmp/test.txt" ] && echo "可读" || echo "不可读"

不可读

5-w判断对象是否可写

此测试同样对root用户无效,无论文件是否设置w权限,root都可写:

[root@svr5~]#chmod -w /tmp/test.txt//去掉所有的w权限

[root@svr5~]#ls -l /tmp/test.txt//确认设置结果

----------1 root root 33139 12-11 10:43/tmp/test.txt

[root@svr5~]#[ -w "/tmp/test.txt" ] && echo "可写" || echo "不可写"

可写

切换为普通用户,可以正常使用-w测试:

[zengye@svr5~]$ls -l /tmp/test.txt

----------1 root root 33139 12-11 10:52/tmp/test.txt

[zengye@svr5~]$[ -w "/tmp/test.txt" ] && echo "可写" || echo "不可写"

不可写

6-x判断对象是否具有可执行权限

这个取决于文件本身、文件系统级的控制,root或普通用户都适用:

[root@svr5~]#chmod 644 /tmp/test.txt//重设权限,无x

[root@svr5~]#ls -l /tmp/test.txt//确认设置结果

-rw-r--r--1 root root 33139 12-11 10:52/tmp/test.txt

[root@svr5~]#[ -x "/tmp/test.txt" ] && echo "可执行" || echo "不可执行"

不可执行

[root@svr5~]#chmod +x /tmp/test.txt//添加x权限

[root@svr5~]#[ -x "/tmp/test.txt" ] && echo "可执行" || echo"不可执行"

可执行

步骤五:多个条件/操作的逻辑组合

1&&,逻辑与

给定条件必须都成立,整个测试结果才为真。

检查变量X的值是否大于10,且小于30

[root@svr5~]#X=20//设置X变量的值为20

[root@svr5~]#[ $X -gt 10 ] && [ $X -lt 30 ] && echo "YES"

YES

2||,逻辑或

只要其中一个条件成立,则整个测试结果为真。

只要/tmp//var/spool/目录中有一个可写,则条件成立:

[root@svr5~]#[ -w "/tmp/" ] || [ -w "/var/spool/" ] && echo "OK"

OK


 案例3:使用if选择结构

3.1问题

本案例要求编写3Shell脚本,分别实现以下目标:

检测/media/cdrom目录,若不存在则创建

检测并判断指定的主机是否可ping

从键盘读取一个论坛积分,判断论坛用户等级,等级分类如下:

大于等于90神功绝世

大于等于80,小于90登峰造极

大于等于70,小于80炉火纯青

大于等于60,小于70略有小成

小于60初学乍练

3.2方案

if单分支的语法组成:

if条件测试

then命令序列

fi

if双分支的语法组成:

if条件测试

then命令序列1

else命令序列2

fi

if多分支的语法组成:

if条件测试1

then命令序列1

elif条件测试2

then命令序列2

else命令序列n

fi

if多分支结构实际上相当于多层if嵌套:

if条件测试1;then

命令序列1

else

if条件测试2;then

命令序列2

else

....

命令序列n

fi

fi

3.3步骤

实现此案例需要按照如下步骤进行。

步骤一:检测/media/cdrom目录,若不存在则创建

1)编写脚本如下:

[root@svr5~]#vim mountdir.sh

#!/bin/bash

dir="/media/cdrom/"

if[ ! -d $dir ]

then

mkdir -p $dir

fi

[root@svr5~]#chmod +x mountdir.sh//添加可执行权限

2)测试、验证脚本功能

[root@svr5~]#ls -ld /media/cdrom//本来没有/media/cdrom目录

ls:/media/cdrom:没有那个文件或目录

[root@svr5~]#./mountdir.sh//执行脚本

[root@svr5~]#ls -ld /media /cdrom//再检查已经有了

drwxr-xr-x 2 root root 4096 12-11 15:16/media/cdrom

有了/media/cdrom文件夹以后,再次执行上述脚本,实际上不做任何有效操作:

[root@svr5~]#./mountdir.sh

[root@svr5~]#

步骤二:检测并判断指定的主机是否可ping

1)分析任务需求

使用ping命令检测目标主机时,人工可直接判断反馈结果,而脚本却不方便。但是当ping测试成功时,执行状态$?的值为0;而ping测试失败时,$?的值不为0。因此在Shell脚本中可以利用这一点来判断ping目标主机的成败。

为了节省ping测试时间,可以只发送3个测试包(-c 3)、缩短发送测试包的间隔秒数(-i 0.2)、等待反馈的超时秒数(-W 3)。比如,检查可ping通的主机:

[root@svr5~]#ping-c 3-i 0.2-W 3 192.168.4.5

PING 192.168.4.5(192.168.4.5)56(84)bytes of data.

64 bytes from 192.168.4.5:icmp_seq=1 ttl=64 time=0.131 ms

64 bytes from 192.168.4.5:icmp_seq=2 ttl=64 time=0.076 ms

64 bytes from 192.168.4.5:icmp_seq=3 ttl=64 time=0.073 ms

---192.168.4.5 ping statistics---

3 packets transmitted,3 received,0%packet loss,time 402ms

rtt min/avg/max/mdev=0.073/0.093/0.131/0.027 ms

[root@svr5~]#echo$?//执行状态表示成功

0

2)脚本编写参考如下:

[root@svr5~]#vim pinghost.sh

#!/bin/bash

ping -c 3 -i 0.2 -W 3 $1 &> /dev/null

if [ $? -eq 0];then

echo "Host $1 is up."

else

echo "Host $1 is down."

fi

[root@svr5~]#chmod +x pinghost.sh

3)测试、验证脚本功能

[root@svr5~]#./pinghost.sh 192.168.4.5

Host 192.168.4.5 is up.

[root@svr5~]#./pinghost.sh 192.168.4.50

Host 192.168.4.50 is down.

步骤三:从键盘读取一个论坛积分,判断论坛用户等级

1)脚本编写参考如下:

大于等于90神功绝世

大于等于80,小于90登峰造极

大于等于70,小于80炉火纯青

大于等于60,小于70略有小成

大于60初学乍练

[root@svr5~]#vim gradediv.sh

#!/bin/bash

read -p "请输入积分(0-100):" JF

if [ $JF -ge 90 ];then

echo"$JF分,神功绝世"

elif [ $JF -ge 80 ];then

echo "$JF分,登峰造极"

elif [ $JF -ge 70 ];then

echo "$JF分,炉火纯青"

elif[ $JFge 60 ];then

echo "$JF分,略有小成"

else

echo "$JF分,初学乍练"

fi

[root@svr5~]#chmod +x gradediv.sh

3)测试、验证脚本

[root@svr5~]#./gradediv.sh

请输入积分(0-100):74

74分,炉火纯青

[root@svr5~]#./gradediv.sh

请输入分数(0-100):68

68分,略有小成

[root@svr5~]#./gradediv.sh

请输入分数(0-100):87

87分,登峰造极

Shell中的数值运算


推荐阅读
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了指针的概念以及在函数调用时使用指针作为参数的情况。指针存放的是变量的地址,通过指针可以修改指针所指的变量的值。然而,如果想要修改指针的指向,就需要使用指针的引用。文章还通过一个简单的示例代码解释了指针的引用的使用方法,并思考了在修改指针的指向后,取指针的输出结果。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 在project.properties添加#Projecttarget.targetandroid-19android.library.reference.1..Sliding ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • PDF内容编辑的两种小方法,你知道怎么操作吗?
    本文介绍了两种PDF内容编辑的方法:迅捷PDF编辑器和Adobe Acrobat DC。使用迅捷PDF编辑器,用户可以通过选择需要更改的文字内容并设置字体形式、大小和颜色来编辑PDF文件。而使用Adobe Acrobat DC,则可以通过在软件中点击编辑来编辑PDF文件。PDF文件的编辑可以帮助办公人员进行文件内容的修改和定制。 ... [详细]
author-avatar
倍儿傻的叶子奇太_900
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有