zoukankan      html  css  js  c++  java
  • Shell编程之运算

    一、变量的数值计算

    1.算术运算符

    常用的运算符号

    常用的运算命令

    (1)双小括号
    基本语法

    1)利用“(())”进行简单运算

    [root@codis-178 ~]# echo $((1+1))
    2
    [root@codis-178 ~]# echo $((6-3))
    3
    [root@codis-178 ~]# ((i=5))
    [root@codis-178 ~]# ((i=i*2))
    [root@codis-178 ~]# echo $i
    10
    

    2)利用“(())”进行复杂运算

    [root@codis-178 ~]# ((a=1+2**3-4%3))
    [root@codis-178 ~]# echo $a
    8
    [root@codis-178 ~]# b=$((1+2**3-4%3))
    [root@codis-178 ~]# echo $b
    8
    [root@codis-178 ~]# echo $((1+2**3-4%3))
    8
    [root@codis-178 ~]# a=$((100*(100+1)/2))
    [root@codis-178 ~]# echo $a
    5050
    [root@codis-178 ~]# echo $((100*(100+1)/2))
    5050
    

    3)特殊运算符的运算

    [root@codis-178 ~]# a=8
    [root@codis-178 ~]# echo $((a=a+1))
    9
    [root@codis-178 ~]# echo $((a+=1))
    10
    [root@codis-178 ~]# echo $((a**2))
    100
    

    4)比较和判断

    [root@codis-178 ~]# echo $((3<8))
    1
    [root@codis-178 ~]# echo $((8<3))
    0
    [root@codis-178 ~]# echo $((8==8))
    1
    [root@codis-178 ~]# if ((8>7&&5==5))
    > then
    > echo yes
    > fi
    yes
    

    5)在变量前后使用--和++特殊运算符的表达式

    [root@codis-178 ~]# a=10
    [root@codis-178 ~]# echo $((a++))
    10
    [root@codis-178 ~]# echo $a
    11
    [root@codis-178 ~]# a=11
    [root@codis-178 ~]# echo $((a--))
    11
    [root@codis-178 ~]# echo $a
    10
    [root@codis-178 ~]# a=10
    [root@codis-178 ~]# echo $a
    10
    [root@codis-178 ~]# echo $((--a))
    9
    [root@codis-178 ~]# echo $((++a))
    10
    [root@codis-178 ~]# echo $a
    10
    

    6)通过“(())”运算后赋值给变量

    [root@codis-178 ~]# myvar=99
    [root@codis-178 ~]# echo $((myvar+1))
    100
    [root@codis-178 ~]# echo $((   myvar+1   ))
    100
    [root@codis-178 ~]# myvar=$((myvar+1))
    [root@codis-178 ~]# echo $myvar
    100
    

    7)包含“(())”的各种常见运算

    [root@codis-178 ~]# echo $((6+2))
    8
    [root@codis-178 ~]# echo $((6-2))
    4
    [root@codis-178 ~]# echo $((6*2))
    12
    [root@codis-178 ~]# echo $((6/2))
    3
    [root@codis-178 ~]# echo $((6%2))
    0
    [root@codis-178 ~]# echo $((6**2))
    36
    

    8)在shell脚本中的示例

    [root@codis-178 ~]# cat test.sh 
    #!/bin/bash
    
    a=6
    b=2
    
    echo "a-b=$(($a-$b))"
    echo "a+b=$(($a+$b))"
    echo "a*b=$(($a*$b))"
    echo "a/b=$(($a/$b))"
    echo "a**b=$(($a**$b))"
    echo "a%b=$(($a%$b))"
    
    [root@codis-178 ~]# sh test.sh 
    a-b=4
    a+b=8
    a*b=12
    a/b=3
    a**b=36
    a%b=0
    

    9)将上面的脚本中a、b两个变量通过命令行脚本传参,以实现混合运算

    [root@codis-178 ~]# cat test.sh 
    #!/bin/bash
    
    a=$1
    b=$2
    
    echo "a-b=$(($a-$b))"
    echo "a+b=$(($a+$b))"
    echo "a*b=$(($a*$b))"
    echo "a/b=$(($a/$b))"
    echo "a**b=$(($a**$b))"
    echo "a%b=$(($a%$b))"
    
    [root@codis-178 ~]# sh test.sh 8 3
    a-b=5
    a+b=11
    a*b=24
    a/b=2
    a**b=512
    a%b=2
    
    [root@codis-178 ~]# sh test.sh 3 6
    a-b=-3
    a+b=9
    a*b=18
    a/b=0
    a**b=729
    a%b=3
    

    10)实现输入2个数进行运算的计算器

    [root@codis-178 ~]# cat yunsuan.sh
    #!/bin/bash
    
    print_usage(){
    	printf "Please enter an integer
    "
    	exit 1
    }
    read -p "Please input first number: " firstnum
    if [ -n "`echo $firstnum|sed 's/[0-9]//g'`" ];then
    	print_usage
    fi
    read -p "Please input the operators: " operators
    if [ "${operators}" != "+" ] && [ "${operators}" != "-" ] && [ "${operators}" != "*" ] && [ "${operators}" != "/" ];then
    	echo "please use (+|-|*|/)"
    	exit 2
    fi
    read -p "Please input second number: " secondnum
    if [ -n "`echo $secondnum|sed 's/[0-9]//g'`" ];then
    	printf_usage
    fi
    echo "${firstnum}${operators}${secondnum}=$((${firstnum}${operators}${secondnum}))"
    [root@codis-178 ~]# sh yunsuan.sh 
    Please input first number: 5
    Please input the operators: +
    Please input second number: 16
    5+16=21
    [root@codis-178 ~]# sh yunsuan.sh 
    Please input first number: 9
    Please input the operators: *
    Please input second number: 24
    9*24=216
    [root@codis-178 ~]# sh yunsuan.sh 
    Please input first number: 76
    Please input the operators: -
    Please input second number: 24
    76-24=52
    

    改良版

    [root@codis-178 ~]# cat yunsuan1.sh 
    #!/bin/bash
    
    print_usage(){
    	printf $"USAGE:$0 NUM1 {+|-|*|/} NUM2
    "
    	exit 1
    }
    if [ $# -ne 3 ]
    	then
    		print_usage
    fi
    firstnum=$1
    secondnum=$3
    op=$2
    if [ -n "`echo $firstnum|sed 's/[0-9]//g'`" ];then
    	print_usage
    fi
    if [ "$op" != "+" ] && [ "$op" != "-" ] && [ "$op" != "*" ] && [ "$op" != "/" ]
    	then
    		print_usage
    fi
    if [ -n "`echo $secondnum|sed 's/[0-9]//g'`" ];then
    	printf_usage
    fi
    echo "${firstnum}${op}${secondnum}=$((${firstnum}${op}${secondnum}))"
    [root@codis-178 ~]# sh yunsuan1.sh 6 + 8
    6+8=14
    [root@codis-178 ~]# sh yunsuan1.sh 56 + 13
    56+13=69
    [root@codis-178 ~]# sh yunsuan1.sh 56 - 13
    56-13=43
    
    [root@codis-178 ~]# sh yunsuan1.sh 2 * 2
    USAGE:yunsuan1.sh NUM1 {+|-|*|/} NUM2
    [root@codis-178 ~]# sh yunsuan1.sh 9 / 3
    9/3=3
    [root@codis-178 ~]# sh yunsuan1.sh 2 * 2  # 乘号需要转义
    2*2=4
    

    (2)let运算命令
    1)给自变量加8

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

    2)监控Web服务状态,如果访问两次均失败,则报警

    [root@codis-178 ~]# cat web.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+=1
    			fi
    			if [ $success -ge 1 ]
    				then
    					echo success
    					exit 0
    			fi
    			if [ $fails -ge 2 ]
    				then
    					Critical="sys is down."
    					echo $Critical|tee|mail -s "$Critical" tongxiaoda@anzhi.com
    					exit 2
    			fi
    	done
    }
    CheckUrl
    [root@codis-178 ~]# sh web.sh 
    success
    

    (3)expr命令
    1)expr用于计算

    [root@codis-178 ~]# expr 2 + 2
    4
    [root@codis-178 ~]# expr 2 - 2
    0
    [root@codis-178 ~]# expr 2 * 2  # 需要转义
    expr: syntax error
    [root@codis-178 ~]# expr 2 * 2
    4
    [root@codis-178 ~]# expr 2 / 2
    1
    

    2)expr配合变量计算

    [root@codis-178 ~]# i=5
    [root@codis-178 ~]# i=`expr $i + 6`
    [root@codis-178 ~]# echo $i
    11
    

    3)判断一个变量或字符串是否为整数

    [root@codis-178 ~]# i=5
    [root@codis-178 ~]# expr $i + 6 &>/dev/null
    [root@codis-178 ~]# echo $?
    0
    [root@codis-178 ~]# i=oldboy
    [root@codis-178 ~]# expr $i + 6 &>/dev/null
    [root@codis-178 ~]# echo $?
    2
    

    4)通过传参判断输出内容是否为整数

    [root@codis-178 ~]# cat expr.sh 
    #!/bin/bash
    expr $1 + 1 > /dev/null 2>&1
    [ $? -eq 0 ] && echo int || echo chars
    [root@codis-178 ~]# sh expr.sh oldboy
    chars
    [root@codis-178 ~]# sh expr.sh 119
    int
    

    5)通过read读入持续等待输入

    [root@codis-178 ~]# cat judge_int.sh 
    #!/bin/bash
    while true
    do
    	read -p "Pls input:" a
    	expr $a + 0 >/dev/null 2>&1
    	[ $? -eq 0 ] && echo int || echo chars
    done
    [root@codis-178 ~]# sh judge_int.sh 
    Pls input:oldgirl
    chars
    Pls input:76
    int
    Pls input:76sd
    chars
    

    6)通过expr判断文件扩展名是否符合要求

    [root@codis-178 ~]# cat expr1.sh 
    #!/bin/bash
    if expr "$1" : ".*.pub" &>/dev/null
    	then
    		echo "you are using $1"
    else
    	echo "Pls use *.pub file"
    fi
    [root@codis-178 ~]# sh expr1.sh ttt.pub
    you are using ttt.pub
    [root@codis-178 ~]# sh expr1.sh ttt.py
    Pls use *.pub file
    

    7)使用expr命令实现ssh服务自带的ssh-copy-id公钥分发脚本

    [root@codis-178 ~]# sed -n '10,20p' which /usr/bin/ssh-copy-id
    sed: can't read which: No such file or directory
    if [ "-i" = "$1" ]; then
      shift
      # check if we have 2 parameters left, if so the first is the new ID file
      if [ -n "$2" ]; then
        if expr "$1" : ".*.pub" > /dev/null ; then
          ID_FILE="$1"
        else
          ID_FILE="$1.pub"
        fi
        shift         # and this should leave $1 as the target name
      fi
    

    8)通过expr计算字符串长度

    [root@codis-178 ~]# char="I am oldboy"
    [root@codis-178 ~]# expr length "$char"
    11
    [root@codis-178 ~]# echo ${char}
    I am oldboy
    [root@codis-178 ~]# echo ${char}|wc -L
    11
    [root@codis-178 ~]# echo ${char}|awk '{print length($0)}'
    11
    

    9)请编写shell脚本,打印下面语句中字符数不大于6的单词
    I am oldboy linux welcome to our training

    [root@codis-178 ~]# cat word_length.sh 
    #!/bin/bash
    for n in I am oldboy linux welcome to our training
    do
    	if [ `expr length $n` -le 6 ]
    		then
    			echo $n
    	fi
    done
    [root@codis-178 ~]# sh word_length.sh 
    I
    am
    oldboy
    linux
    to
    our
    

    (4)bc命令
    Linux内部计算器

    [root@codis-178 ~]# 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'. 
    1+1
    2
    3*3
    9
    

    1)将bc用在命令行实现运算

    [root@codis-178 ~]# echo 3+5|bc
    8
    [root@codis-178 ~]# echo 3.3+5.6|bc
    8.9
    [root@codis-178 ~]# echo 7.28-5.62|bc
    1.66
    [root@codis-178 ~]# echo "scale=2;355/113"|bc  # scale保留几位小数
    3.14
    [root@codis-178 ~]# echo "scale=4;355/113"|bc
    3.1415
    [root@codis-178 ~]# i=5
    [root@codis-178 ~]# i=`echo $i+6|bc`
    [root@codis-178 ~]# echo $i
    11
    

    2)通过一条命令计算输出1+2+3+...+10的表达式,并计算结果

    [root@codis-178 ~]# echo `seq -s '+' 10`=`seq -s "+" 10|bc`
    1+2+3+4+5+6+7+8+9+10=55
    [root@codis-178 ~]# echo `seq -s '+' 10`=$((`seq -s "+" 10`))
    1+2+3+4+5+6+7+8+9+10=55
    [root@codis-178 ~]# echo `seq -s "+" 10`=`seq -s " + " 10|xargs expr`
    1+2+3+4+5+6+7+8+9+10=55
    

    (5)awk实现计算

    [root@codis-178 ~]# echo "7.73 3.854" |awk '{print ($1-$2)}'
    3.876
    [root@codis-178 ~]# echo "367 131" |awk '{print ($1-3)/$2}'
    2.77863
    

    (6)$[]符号的运算

    [root@codis-178 ~]# i=5
    [root@codis-178 ~]# i=$[i+6]
    [root@codis-178 ~]# echo $i
    11
    [root@codis-178 ~]# echo $[2*3]
    6
    [root@codis-178 ~]# echo $[3%5]
    3
    

    打印数学杨辉三角

    [root@codis-178 ~]# cat shuxue.sh 
    #!/bin/bash
    if (test -z $1);then
    	read -p "Input Max Lines:" MAX
    else
    	MAX=$1
    fi
    i=1
    while [ $i -le $MAX ]
    do
    	j=1
    	while [ $j -le $i ]
    	do
    		f=$[i-1]
    		g=$[j-1]
    		if [ $j -eq $i ] || [ $j -eq 1 ];then
    			declare SUM_${i}_$j=1
    		else
    			declare A=$[SUM_${f}_$j]
    			declare B=$[SUM_${f}_$g]
    			declare SUM_${i}_$j=`expr $A + $B`
    		fi
    		echo -en $[SUM_${i}_$j]" "
    		let j++
    	done
    	echo
    	let i++
    done
    
    [root@codis-178 ~]# sh shuxue.sh 
    Input Max Lines:4
    1 
    1 1 
    1 2 1 
    1 3 3 1
    

    2.基于Shell变量输入read命令的运算

    (1)read命令
    语法格式:read [参数] [变量名]
    参数:

    • -p prompt 设置提示信息
    • -t timeout 设置输入等待时间,单位秒
    [root@codis-178 ~]# read -t 10 -p "Pls input one num:" num
    Pls input one num:18
    [root@codis-178 ~]# echo $num
    18
    [root@codis-178 ~]# read -t 10 -p "Pls input two num:" a1 a2
    Pls input two num:5 6
    [root@codis-178 ~]# echo $a1
    5
    [root@codis-178 ~]# echo $a2
    6
    

    (2)以read命令读取及传参的综合案例

    [root@codis-178 ~]# cat read_size01.sh 
    #!/bin/bash
    read -t 15 -p "Please input two number:" a b
    
    [ ${#a} -le 0 ] && {
    	echo "the first num is null"
    	exit 1
    }
    [ ${#b} -le 0 ] && {
    	echo "the second num is null"
        exit 1
    }
    
    expr $a + 1 &>/dev/null
    RETVAL_A=$?
    expr $b + 1 &>/dev/null
    RETVAL_B=$?
    if [ $RETVAL_A -ne 0 -o $RETVAL_B -ne 0 ];then
    	echo "one of the num is not num,pls input again."
    	exit 1
    fi
    
    echo "a-b=$(($a-$b))"
    echo "a+b=$(($a+$b))"
    echo "a*b=$(($a*$b))"
    echo "a/b=$(($a/$b))"
    echo "a**b=$(($a**$b))"
    echo "a%b=$(($a%$b))"
    [root@codis-178 ~]# sh read_size01.sh 
    Please input two number:qq
    the second num is null
    [root@codis-178 ~]# sh read_size01.sh 
    Please input two number:12 6
    a-b=6
    a+b=18
    a*b=72
    a/b=2
    a**b=2985984
    a%b=0
    

    通过传参方式

    [root@codis-178 ~]# cat read_size02.sh 
    #!/bin/bash
    a=$1
    b=$2
    Usage(){
    	echo $"USAGE:sh $0 num1 num2"
    	exit 1
    }
    if [ $# -ne 2 ];then
    	Usage
    fi
    expr $a + 1 >/dev/null 2>&1
    [ $? -ne 0 ] && Usage
    
    echo "a-b=$(($a-$b))"
    echo "a+b=$(($a+$b))"
    echo "a*b=$(($a*$b))"
    echo "a**b=$(($a**$b))"
    if [ $b -eq 0 ]
    	then
    		echo "your input does not allow to run"
    		echo "a/b =error"
    		echo "a%b =error"
    else
    	echo "a/b =$(($a/$b))" 
    	echo "a%b =$(($a%$b))"
    fi
    
    [root@codis-178 ~]# sh read_size02.sh 
    USAGE:sh read_size02.sh num1 num2
    [root@codis-178 ~]# sh read_size02.sh 7 old
    USAGE:sh read_size02.sh num1 num2
    [root@codis-178 ~]# sh read_size02.sh 7 3
    a-b=4
    a+b=10
    a*b=21
    a**b=343
    a/b =2
    a%b =1
    
  • 相关阅读:
    MathType如何插入竖直线
    MongoDB时间类型
    《穆斯林的葬礼》读书笔记
    Fluentd安装——通过rpm方式
    MongoDB安装、管理工具、操作
    Flask服务入门案例
    python判断类型
    linux硬链接与软链接
    python 环境问题
    Linux进程管理工具——supervisor
  • 原文地址:https://www.cnblogs.com/tongxiaoda/p/7454566.html
Copyright © 2011-2022 走看看