zoukankan      html  css  js  c++  java
  • shell 编程 05 -- 变量的数值计算实践(read、let、expr、bc、declare、awk、杨辉三角)

    变量的数值计算实践

    5.1 算术运算符

    常见的算术运算符号

    算术运算符 意义
    + 、- 加、减
    *、/、% 乘、除、取余(取模)
    ** 幂运算
    ++、-- 自增、自减
    !、&&、|| 逻辑非、逻辑与、逻辑或
    <、<=、>>= 比较符号
    ==、!=、= 比较符号
    <<、>> 向左移位、向右移位
    ~、| 、&、^ 按位取反、按位异或、按位与、按位或
    =、+=、-=、*=、/=、%= 赋值运算符,a+=1等价于a=a+1

    shell中常见的算术运算命令

    运算操作符与运算命令 意义
    (()) 整数运算
    let 整数运算,类似于(())
    expr 整数运算,有额外功能
    bc 适合整数和小数运算
    $[] 整数运算
    awk 适合整数和小数运算
    declare 定义变量值和属性,-i参数可用于定义整数变量做运算

    5.2 双小括号"(())"整数数值运算命令


    双小括号“(())”的作用是进行数值运算与数值比较,它的效率很高,用法灵活,是企业场景运维人员经常采用的运算操作符


    双小括号“(())”的操作方法

    运算操作符与运算命令 意义-- 只能做整数运算
    ((i=i+1)) 将i+1的结果赋值给i;echo $((i=i+1))输出结果
    i=$((i+1)) 在(())前加$符,表示将运算结果赋值给i
    ((8>7&&5==5)) 比较操作,可加入逻辑符号,用于条件判断
    echo $((2+1)) 在(())前加$,可直接输出运算表达式的运算结果

    双小括号“(())”数值运算实践

    ## 数值运算
    [root@zabbix ~]# a=8
    [root@zabbix ~]# echo $((a=a+1))
    9
    [root@zabbix ~]# echo $((a+=1))
    10
    [root@zabbix ~]# echo $a
    10
    [root@zabbix ~]# echo $((a**2))
    100
    --------------------------------------
    ## 比较判断
    [root@zabbix ~]# echo $((3<8))  --- 结果为真,输出1
    1
    [root@zabbix ~]# echo $((3>8))  --- 结果为假,输出0
    0
    [root@zabbix ~]# echo $((3==3))  --- 结果为真,输出1
    1
    [root@zabbix ~]# if ((8>7&&5==5)) --- 作为判断条件
    > then
    > echo yes
    > fi
    yes	--- 输出结果
    [root@zabbix ~]#
    -------------------------------------------------------
    ## 自增自减
    [root@zabbix ~]# a=10
    [root@zabbix ~]# echo $((a++))   -- a++,表示先输出a的值10,a再自增1,a=11
    10
    [root@zabbix ~]# echo $a
    11
    [root@zabbix ~]# a=11
    [root@zabbix ~]# echo $((a--))   -- a--,表示先输出a的值111,a再自减1,a=10
    11
    [root@zabbix ~]# echo $a
    10
    [root@zabbix ~]# a=10
    [root@zabbix ~]# echo $((++a))   -- ++a,表示先输出a+1的值,a再自增1=11
    11
    [root@zabbix ~]# echo $a
    11
    [root@zabbix ~]# a=11
    [root@zabbix ~]# echo $((--a))   -- --a,表示先输出a-1的值,a再自减1=10
    10
    [root@zabbix ~]# echo $a
    10
    --执行echo $((a++))和echo $((a--))命令输出整个表达式时,输出的值即为a的值,表达式执行完毕后,会对a进行++、--的运算,
    --而执行echo $((++a))和echo $((--a))命令输出整个表达式时,会先对a进行++、--的运算,然后再输出表达式的值,即为a运算后的值。
    

    5.2.3 read 方式实现简单计算器

    read 方式实现简单计算器,等价于echo $((num1 * num2))

    [root@zabbix 0506]# cat read.sh 
    #!/bin/bash
    # add,sub,multi,divide caculate by moox.
    print_usage(){
        printf "Please enter an integer
    "
        exit 1
    }
    read -p "Please input first number:" firstnum
    if [ -z $firstnum ] || [ -n "`echo $firstnum|sed 's/[0-9]//g'`" ]
        then 
    	print_usage
    fi
    read -p "Please input the aperations:" operators
    if [ "$operators" != "+" ] && [ "$operators" != "-" ]&& [ "$operators" != "*" ]&&[ "$operators" != "/" ]
        then
    	echo "please input {+|-|*|/}"
    	exit 2
    fi
    read -p "Please input second number:" secondnum
    if [ -z $secondnum ] || [ -n "`echo $secondnum|sed 's/[0-9]//g'`" ]
        then
            print_usage
    fi
    echo "${firstnum}${operators}${secondnum}=$((${firstnum}${operators}${secondnum}))"
    -------------------
    ## 等价用法
    [root@zabbix 0506]# cat cacu.sh 
    echo $(($1))
    [root@zabbix 0506]# sh cacu.sh "2 * 100"
    200
    
    

    5.3 let 运算命令的用法


    let运算命令的语法格式为:let赋值表达式
    let赋值表达式的功能等同于“((赋值表达式))”


    5.3.1 用法:

    [root@zabbix ~]# unset i
    [root@zabbix ~]# i=2
    [root@zabbix ~]# let i=i+8
    [root@zabbix ~]# echo $i
    10
    

    5.3.2 let应用案例:监控Web服务状态

    监控Web服务状态,如果访问两次均失败,则报警(let应用案例)

    [root@zabbix 0506]# cat check_url.sh 
    #!/bin/bash
    CheckUrl(){
      timeout=5
      fails=0
      success=0
      while true
      do
    	wget --timeout=$timeout --tries=1 http://oldboy.blog.51cto.com -q -O /dev/null
    	if [ $? -ne 0 ]
    	then
    		let fails=fails+1
    	else
    		let success=success+1
    	fi      
    	if [ $success -ge 1 ]
    	then
    		echo success
    		exit 0
    	fi
    	if [ $fails -le 2 ]
    	then
    		Critical="sys is down."
    		echo $Critical|tee|mail -s "$Critical" 2144865225@qq.com
    		exit 2
    	fi
      done
    }
    CheckUrl
    [root@zabbix 0506]# sh check_url.sh 
    success
    

    5.4 expr命令的用法


    expr(evaluate(求值)expressions(表达式))命令既可以用于整数运算,也可以用于相关字符串长度、匹配等的运算处理。


    5.4.1 expr用于计算语法:expr Expression

    [root@zabbix 0506]# expr 2+2
    2+2
    [root@zabbix 0506]# expr 2 + 2
    4
    [root@zabbix 0506]# expr 2 - 2
    0
    [root@zabbix 0506]# expr 2 * 2
    expr: syntax error
    [root@zabbix 0506]# expr 2 * 2
    4
    [root@zabbix 0506]# expr 2 / 2
    1
    ## 要注意,在使用expr时:
    运算符及用于计算的数字左右都至少有一个空格,否则会报错。
    使用乘号时,必须用反斜线屏蔽其特定含义,因为Shell可能会误解星号的含义。
    

    5.4.2 expr配合变量计算

    expr在Shell中可配合变量进行计算,但需要用反引号将计算表达式括起来。

    [root@zabbix 0506]# i=5
    [root@zabbix 0506]# i=`expr $i + 6`
    [root@zabbix 0506]# echo $i
    11
    

    5.4.3 expr 实例:判断变量值是否为整数


    判断一个变量值或字符串是否为整数:利用以expr做计算时变量或字符串必须是整数的规则,把一个变量或字符串和一个已知的整数(非0)相加,看命令返回的值是否为0。如果为0,就认为做加法的变量或字符串为整数,否则就不是整数


    1. 通过expr判断变量或字符串是否为整数。
    [root@zabbix 0506]# i=5
    [root@zabbix 0506]# expr $i + 6
    11							-- 可将结果> /dev/null,不做输出
    [root@zabbix 0506]# echo $?
    0			--- 结果为0
    [root@zabbix 0506]# i=oldboy
    [root@zabbix 0506]# expr $i + 6
    expr: non-integer argument	-- 可将结果> /dev/null,不做输出
    [root@zabbix 0506]# echo $?
    127			--- 结果非0
    
    1. 通过传参判断输出内容是否为整数
    [root@zabbix 0506]# cat expr.sh 
    #!/bin/bash
    expr $1 + 1 > /dev/null 2>&1
    [ $? -eq 0 ] && echo int || echo chars
    -----------------------------------------------
    [root@zabbix 0506]# sh expr.sh  11
    int
    [root@zabbix 0506]# sh expr.sh aa
    chars
    
    1. 通过read读入持续等待输入例子
    [root@zabbix 0506]# cat read_expr.sh 
    #!/bin/bash
    while true
    do
        read -p "Pls input :" a
        expr $a + 1 >/dev/null 2>&1
        [ $? -eq 0 ] && echo int ||echo chars
    done
    -------------------------------------------------
    [root@zabbix 0506]# sh read_expr.sh 
    Pls input :ss
    chars
    Pls input :277
    int
    Pls input :^C
    

    5.4.4 expr的特殊用法(扩展名判断)

    1. 通过expr判断文件扩展名是否符合要求
    [root@zabbix 0506]# cat expr_end.sh 
    #!/bin/bash
    if expr "$1" : ".*.pub" &>/dev/null
      then 
        echo "you are using $1"
    else
        echo "please use *.pub file."
    fi
    ----------------------------------------
    [root@zabbix 0506]# sh expr_end.sh aa
    please use *.pub file.
    [root@zabbix 0506]# sh expr_end.sh aa.pub
    you are using aa.pub
    [root@zabbix 0506]# 
    
    1. 使用expr命令实现系统ssh服务自带的ssh-copy-id公钥分发脚本。
    [root@zabbix 0506]# cat ssh-copy-id.sh 
    #!/bin/bash
    echo "$0 $1 $2 $3 "
    if [ "-i" = "$1" ];then
        shift
        echo "$1 $2"
        if [ -n "$2" ];then
            if expr "$1" : ".*.pub" &>/dev/null;then
    	  ID_FILE="$1"
    	else
    	  ID_FILE="$1.pub"
    	fi
    	echo $ID_FILE
        fi
    fi
    --------------------------------------------------------------------
    [root@zabbix 0506]# sh ssh-copy-id.sh -i aa root@172.16.1.31:~/
    ssh-copy-id.sh -i aa root@172.16.1.31:~/ 
    aa root@172.16.1.31:~/
    aa.pub
    
    1. expr 实现Shell脚本,打印下面语句中字符数不大于6的单词

    I am oldboy linux,welcome to our training.

    for n in `echo "I am oldboy linux,welcome to our training."|tr ",|." " "`
    do
    	if [ `expr length "$n"` -le 6 ]
    		then
    		echo $n
    	fi
    done
    

    5.5 bc命令的用法

    5.5.1 bc作为计算器来应用,直接bc命令

    [root@zabbix 0506]# 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'. 
    45-14*515-47+4
    -7208
    

    5.5.2 bc作为命令行来应用

    [root@zabbix 0506]# echo 3+2|bc
    5
    [root@zabbix 0506]# echo 3+2.556|bc
    5.556
    [root@zabbix 0506]# echo "scale=3;3/2.556"|bc
    1.173
    [root@zabbix 0506]# echo "scale=7;3/2.556"|bc
    1.1737089
    

    5.5.3 bc计算输出1+2+…+10

    # 通过一条命令计算输出1+2+3+…+10的表达式,并计算出结果,请使用bc命令计算。
    # 输出内容如1+2+3+4+5+6+7+8+9+10=55
    [root@zabbix 0506]# echo "`seq -s "+" 10`=`seq -s "+" 10|bc`"
    1+2+3+4+5+6+7+8+9+10=55	
    

    5.6 awk 实现计算


    利用awk进行运算的效果也很好,适合小数和整数,特别是命令行计算,尤其是小数,运算很精确,好用。来看个示例,如下:


    [root@zabbix 0506]# echo "3 9"|awk '{print ($1-$2)/4}'
    -1.5
    

    5.7 declare(同typeset)命令的用法

    使用typeset定义整数变量,直接进行计算

    [root@zabbix 0506]# declare -i A=30 B=7	## declare -i参数可以将变量定义为整形
    [root@zabbix 0506]# A=A+B				## 已声明是整形,可以直接计算
    [root@zabbix 0506]# echo $A
    37
    

    5.8 $[] 符号的运算实例

    5.8.1 打印数学杨辉三角

    [root@zabbix 0506]# cat yanghsj.sh 
    #!/bin/bash
    if (test -z $1)						-- 判断传参的长度是否为0
      then
        read -p "Input Max Lines:" MAX	-- 读入参数
      else
        MAX=$1							-- 已经传参,则赋值
    fi
    i=1									-- 初始行为1
    while [ $i -le $MAX ]				-- 行数控制
    do 
        j=1								-- 初始列为1
        while [ $j -le $i ]				-- 列数控制,列数小于等于行数
        do
    		f=$[i-1]					-- 取位置:当前行的上一行
    		g=$[j-1]					-- 取位置:当前列的前一列
    		if [ $j -eq $i ]||[ $j -eq 1 ]	-- 控制首列值(j=1),尾列值(j=i)
    	  	then
    	      	declare SUM_${i}_$j=1		-- 控制每行的第一列和最后一列值都是1
    		else
    	    	declare  A=$[SUM_${f}_$g]	-- 取值:上一行前一列的值
    	    	declare  B=$[SUM_${f}_$j]	-- 取值:上一行当前列的值
    	    	## 取值:当前行当前列的值=上一行前一列的值+上一行当前列的值
    	    	declare  SUM_${i}_$j=`expr $A + $B`	
    		fi
    		echo -en $[SUM_${i}_${j}]		-- 不换行输出每行每列的值
    		let j++							-- 列值+1
        done
        echo 								-- 取完每行的所有列值,输出换行
        let i++								-- 行值+1
    done
    
    

    5.9 基于shell变量输入read命令的运算实践


    语法格式:read [参数] [变量名]
    常用参数如下。
    -p prompt:设置提示信息。
    -t timeout:设置输入等待的时间,单位默认为秒


    1. 功能演示:
    # -t 参数指定等待时间,10秒后退出读取
    # -p 参数指定提示信息
    # 不使用参数时,直接跟变量
    [root@zabbix 0506]# read -t 10 -p "please input a num:"  num1
    please input a num: 100
    [root@zabbix 0506]# echo $num1
    100
    [root@zabbix 0506]# read aa bb
    1001 1002
    [root@zabbix 0506]# echo $aa ;echo $bb
    1001
    1002
    
    1. read -p 功能可用echo -n 实现
    [root@zabbix 0506]# echo -n "please input a num:"  && read num1
    please input a num:100
    [root@zabbix 0506]# echo $num1
    100
    
  • 相关阅读:
    IDEA解决Cannot download sources的问题
    Swagger在Springboot项目中的使用
    ElasticSearch(10)—SpringBoot集成ES
    ElasticSearch(9)---Rest风格
    ElasticSearch(8)---IK分词器
    js显示原型和隐示原型
    通俗易懂讲解为什么设计稿都是750px
    关于rem和px全局设置问题
    PHP RSA密文过长加密解密 越过1024的解决代码
    使用https,$_SERVER['HTTPS']却不等于on?
  • 原文地址:https://www.cnblogs.com/moox/p/12835198.html
Copyright © 2011-2022 走看看