zoukankan      html  css  js  c++  java
  • shell脚本之算术运算和逻辑运算

    目录

       算术运算

       赋值运算

       逻辑运算

    短路运算和异或

    条件测试

    数值测试

    字符串测试

    文件及其属性测试

       存在性测试

    存在性及类别测试

    文件权限测试

    文件特殊权限测试

    文件大小测试

    文件是否打开

    双目测试

       组合测试条件

       扩展

          read命令

          配置文件相关

          Bash退出任务

          关于$-变量

     

    算术运算

    Bash中我们可以进行算术运算,包括:+-*/%**,分别是加,减,乘,除,取余,乘方。我们有六种方式,实现上面的运算:

    (1) let var=算术表达式

    (2) var=$[算术表达式]

    (3) var=$((算术表达式))

    (4) var=$(expr arg1 arg2 arg3 ...)

    (5) declare i var = 数值

    (6) echo ‘算术表达式’ | bc

    有一点需要注意的是*在运算中需要转译即“*

    [root@CT71 ~]#let var1=1234
    [root@CT71 ~]#var2=$[12+32]
    [root@CT71 ~]#var3=$((12+12))
    [root@CT71 ~]#var4=$( expr 1 + 2 + 3 + 4 )
    [root@CT71 ~]#echo $var1 $var2 $var3 $var4
    1234 44 24 10
    [root@CT71 ~]#let var5=2**10
    [root@CT71 ~]#let var6=2*10
    [root@CT71 ~]#echo "3 * 4" | bc
    12
    [root@CT71 ~]#var7=$( expr 3 * 5 )
    [root@CT71 ~]#echo $var5 $var7
    1024 15

    除此以外bash中还有内建的随机数生成器:$RANDOM0-32767

    如:

       echo $[$RANDOM%50] 0-49之间随机数

    在算术运算和增强型赋值中,要使用letlet的具体用法请自行man let,它的功能是数字型运算和增强型赋值(下面会讲到)

    [root@CT71 ~]#echo $[$RANDOM%50]
    12
    [root@CT71 ~]#echo $[$RANDOM%50]
    25
    [root@CT71 ~]#echo $[$RANDOM%50]
    39
    [root@CT71 ~]#echo $[$RANDOM%50]
    19
    [root@CT71 ~]#

    赋值

    变量赋值,我们通常使用“=”,比如var=1234,就是把数值1234赋给var这个变量,此外我们还有其他的赋值方式,

    增强型赋值方式:

       +=, -=, *=, /=, %=

       比如:

          var=2

    let var+=23

    这是var的值是25

    除此以外,还有自增,自减:

       let var+=1

    let var++

    let var-=1

    let var--

    [root@CT71 ~]#var=2
    [root@CT71 ~]#let var+=23
    [root@CT71 ~]#echo $var
    25
    [root@CT71 ~]#let var++
    [root@CT71 ~]#echo $var
    26
    [root@CT71 ~]#let var-=1
    [root@CT71 ~]#echo $var
    25
    [root@CT71 ~]#

    逻辑运算

    我们在编写脚本中无论如何都少不了逻辑判断,我们通过逻辑判断来进行我们需要进行的操作,完成我们需要的功能。现在我们先看一下最基本的逻辑功能。

    true1false0

    与:

    1 1 = 1

    1 0 = 0

    0 1 = 0

    0 0 = 0

    :

    1 1 = 1

    1 0 = 1

    0 1 = 1

    0 0 = 0

    这是我们最基本的逻辑与和或的关系,我们所有的逻辑判断都是基于这些基本的逻辑判断上的。在基本的逻辑中还有一个判断那就是“非”或“!”代表的是一个意思即!1=0,!0=1

    短路运算,异或

    短路与(&&

       第一个为0,结果必定为0

    第一个为1,第二个必须要参与运算

    短路或(||

       第一个为1,结果必定为1

    第一个为0,第二个必须要参与运算

    异或(^

       异或的两个值,相同为假,不同为真

    A && B
      当A为0时,不再执行B
      当A为1时,还会执行B
    A
    || B
      当A为1时,不再执行B
      当A为0时,继续执行A
    A
    ^ B
      当A == B,为真
      当A != B,为假

    条件测试

    linux脚本中,我们需要一些工具来帮助我们完成逻辑的判断,通过判断真假条件,在通过逻辑运算符来指定判断出真假后我们需要进一步做些什么,在linux中,有评估布尔声明,以便用在条件执行中:

       若真,返回0

    若假,返回1

    我们一般的判断命令如下:

       test expression

    [exoression]

    [[expression]]

    对于这三种判断方法,我们一般使用最多的是后两种

    注意: EXPRESSION前后必须有空白字符

    示例:

    [ "$A" == "$B" ] && echo "Strings are equal"

    [ "$A" -eq "$B" ] && echo "Integers are equal"

    [root@CT6 man]# A=23
    [root@CT6 man]# B=24
    [root@CT6 man]# [ $A -eq $B ] && echo "YES" || echo "NO"
    NO
    [root@CT6 man]# 

    判断一个变量是否设置,如果我们需要用一个变量,但不知道这个变来那个是否存在,我们可以使用-v来判断这个变量是否存在。

    [  -v VAR ] && echo “变量存在” || echo “变量不存在

    [root@CT6 man]# set | grep "^A"
    [root@CT6 man]# [ -v $A ] && echo "YES" || echo "NO"
    YES
    [root@CT6 man]# 

    数值测试

    在脚本中那我们很多时候需要判断数字的大小,而linux中给我们提供了一种判断数字大小的方法,配合条件判断来进行使用:

    -gt 是否大于

    -ge 是否大于等于

    -eq 是否等于

    -ne 是否不等于

    -lt 是否小于

    -le 是否小于等于

    示例:

       [ 23 –gt 22 ] && echo “true” || echo “false”

       [ 66 –ge 66 ] && echo “true” || echo “false”

    [root@CT6 man]# [ 23 -gt 22 ] && echo "true" || echo "false" 
    true
    [root@CT6 man]# [ 66 -ge 66 ] && echo "true" || echo "false" 
    true

    字符串测试

       除了数值测试完,还有字符串测试,用于测试字符是否相同等。

      

    == 是否等于

    > ascii码是否大于ascii

    < 是否小于

    != 是否不等于

    =~ 左侧字符串是否能够被右侧的PATTERN所匹配

    注意: 此表达式一般用于[[ ]]中;扩展的正则表达式

    [root@CT6 man]# str1=LiuDehua
    [root@CT6 man]# str2=LiuDehua
    [root@CT6 man]# [ "$str1" == "$str2" ] && echo "=" || echo '!='
    =
    [root@CT6 man]# A=string_1234
    [root@CT6 man]# [[ $A =~ [[:alpha:]]+[_][0-9]* ]] && echo "匹配" || echo "不匹配"
    匹配
    
    [root@CT6 man]# [[ $A =~ ^[[:digit:]] ]] && echo "匹配" || echo "不匹配"     
    不匹配

    -z "STRING 字符串是否为空,空为真,不空为假

    -n "STRING 字符串是否不空,不空为真,空为假

    注意:用于字符串比较时的用到的操作数都应该使用引号

    [root@CT6 man]# [ -z " " ] && echo "true" || echo "false"
    false
    [root@CT6 man]# [ -z "" ] && echo "true" || echo "false" 
    true
    [root@CT6 man]# [ -n "string" ] && echo "true" || echo "false" 
    true
    [root@CT6 man]# [ -n "" ] && echo "true" || echo "false"      
    false

     

    文件及属性测试

    在脚本中我们很多时候要对文件进行处理,那么对文件的判断就显得尤为重要,包括文件是否存在,文件的类型,文件的权限,文件的大小,文件的修改访问时间等,我们通过一定的方式可以实现对文件的各种判断,然后就可以实现我们的目的。

     

    存在性测试

    -a FILE:同-eand也是-a 一般使用-e

    -e FILE: 文件存在性测试,存在为真,否则为假

    [root@CT6 tmp]# echo 12345 >> test1.txt
    [root@CT6 tmp]# ll
    total 4
    -rw-r--r--. 1 root root 6 Aug 15 15:04 test1.txt
    [root@CT6 tmp]# [ -e test1.txt ] && echo "true" || echo "false"
    true
    [root@CT6 tmp]# rm test1.txt 
    rm: remove regular file `test1.txt'? y
    [root@CT6 tmp]# [ -e test1.txt ] && echo "true" || echo "false"
    false

     

    存在性及类别测试

    -b FILE:是否存在且为块设备文件

    -c FILE:是否存在且为字符设备文件

    -d FILE:是否存在且为目录文件

    -f FILE:是否存在且为普通文件

    -h FILE -L FILE:存在且为符号链接文件

    -p FILE:是否存在且为命名管道文件

    -S FILE:是否存在且为套接字文件

    [root@CT6 tmp]# [ -b /dev/sda ] && echo "YES" || echo "NO"
    YES
    [root@CT6 tmp]# [ -d /dev ] && echo "YES" || echo "NO"     
    YES
    [root@CT6 tmp]# [ -h /lib64 ] && echo "YES" || echo "NO"     
    NO

     

    文件权限测试

    -r FILE:是否存在且可读

    -w FILE: 是否存在且可写

    -x FILE: 是否存在且可执行

    [du@CT6 ~]$ cd /tmp/
    [du@CT6 /tmp]$ ll
    total 0
    ---x--x--x. 1 root root 0 Aug 15 15:12 du1.doc
    --w--w--w-. 1 root root 0 Aug 15 15:12 du2.doc
    -rw-r--r--. 1 root root 0 Aug 15 15:12 du3.doc
    -rw-r--r--. 1 root root 0 Aug 15 15:12 du4.doc
    [du@CT6 /tmp]$ [ -r du1.doc  ] && echo "YES" || echo "NO"
    NO
    [du@CT6 /tmp]$ [ -r du3.doc ] && echo "YES" || echo "NO" 
    YES
    [du@CT6 /tmp]$ [ -w du1.doc ] && echo "YES" || echo "NO"  
    NO
    [du@CT6 /tmp]$ [ -w du3.doc ] && echo "YES" || echo "NO" 
    NO
    [du@CT6 /tmp]$ [ -w du2.doc ] && echo "YES" || echo "NO" 
    YES

     

    文件特殊权限测试

    -u FILE:是否存在且拥有suid权限

    -g FILE:是否存在且拥有sgid权限

    -k FILE:是否存在且拥有sticky权限 

    [root@CT6 tmp]# ll
    total 0
    -rwSr-Sr--. 1 root root 0 Aug 15 15:23 lianxi_1.doc
    -rwSr--r--. 1 root root 0 Aug 15 15:23 lianxi_2.doc
    -rw-r--r-T. 1 root root 0 Aug 15 15:23 lianxi_3.doc
    -rw-r--r--. 1 root root 0 Aug 15 15:23 lianxi_4.doc
    [root@CT6 tmp]# [ -u lianxi_2.doc ] && echo "YES" || echo "NO"
    YES
    [root@CT6 tmp]# [ -u lianxi_3.doc ] && echo "YES" || echo "NO" 
    NO
    [root@CT6 tmp]# [ -k lianxi_3.doc ] && echo "YES" || echo "NO" 
    YES
    [root@CT6 tmp]# [ -g lianxi_1.doc ] && echo "YES" || echo "NO"   
    YES

     

    文件大小测试

    -s FILE: 是否存在且非空 

    [root@CT6 tmp]# touch tty1
    [root@CT6 tmp]# echo qqq > tty2
    [root@CT6 tmp]# [ -s tty1 ] && echo "NOT empty" || echo "empty"
    empty
    [root@CT6 tmp]# [ -s tty2 ] && echo "NOT empty" || echo "empty" 
    NOT empty

     

    文件是否打开

    -t fd: fd表示文件描述符是否已经打开且与某终端相关

    -N FILE:文件自动上一次被读取之后是否被修改过

    -O FILE:当前有效用户是否为文件属主

    -G FILE:当前有效用户是否为文件属组 

    [root@CT6 tmp]# [ -O tty2 ] && echo "YES" || echo "NO"             
    YES
    [root@CT6 tmp]# [ -G tty2 ] && echo "YES" || echo "NO" 
    YES
    [root@CT6 tmp]# ll
    total 8
    -rw-r--r--. 1 root root    0 Aug 15 15:27 tty1
    -rw-r--r--. 1 root root    4 Aug 15 15:27 tty2

     

    双目测试

    FILE1 -ef FILE2: FILE1FILE2是否指向同一个设备上的相同inode

    FILE1 -nt FILE2: FILE1是否新于FILE2mtime

    FILE1 -ot FILE2: FILE1是否旧于FILE2

    [root@CT6 tmp]# echo qqq > txt
    [root@CT6 tmp]# ln txt txt_ln
    [root@CT6 tmp]# ll
    total 8
    -rw-r--r--. 2 root root 4 Aug 15 15:31 txt
    -rw-r--r--. 2 root root 4 Aug 15 15:31 txt_ln
    [root@CT6 tmp]# [ txt -ef txt_ln ] && echo "YES" || echo "NO"
    YES
    
    [root@CT6 tmp]# touch old
    [root@CT6 tmp]# touch new
    [root@CT6 tmp]# [ old -ot new ] && echo "YES" || echo "NO"         
    YES
    [root@CT6 tmp]# [ old -nt new ] && echo "YES" || echo "NO" 
    NO

    组合测试条件

    第一种方式:

    COMMAND1 && COMMAND2 并且

    COMMAND1 || COMMAND2 或者

    ! COMMAND

    如: [[ -r FILE ]] && [[ -w FILE ]]

    第二种方式:

    EXPRESSION1 -a EXPRESSION2 并且

    EXPRESSION1 -o EXPRESSION2 或者

    ! EXPRESSION

    必须使用测试命令进行

    两种方法都能用,但是个人倾向于使用第二种,因为看起来简单,方便

    [root@CT6 tmp]# echo "@@@@@@@" > tty
    [root@CT6 tmp]# touch tty2
    [root@CT6 tmp]# [ -f tty -a -s tty2 ] && echo "YES" || echo "No"
    No

    扩展

    read命令

    使用read来把输入值分配给一个或多个shell变量

    -p 指定要显示的提示

    -s 静默输入,一般用于密码

    -n N 指定输入的字符长度N

    -d ‘字符’ 输入结束符

    -t N TIMEOUTN

    read 从标准输入中读取值,给每个单词分配一个变量

    所有剩余单词都被分配给最后一个变量

    read -p “Enter a filename: “ FILE

    一般用于脚本中

    bash的配置文件

    按生效范围划分,存在两类:

    全局配置:

    /etc/profile

    /etc/profile.d/*.sh

    /etc/bashrc

    个人配置:

    ~/.bash_profile

    ~/.bashrc

    shell登录两种方式

    交互式登录:

    (1)直接通过终端输入账号密码登录

    (2)使用“su - UserName 切换的用户

    执行顺序:/etc/profile --> /etc/profile.d/*.sh -->~/.bash_profile --> ~/.bashrc --> /etc/bashrc

    非交互式登录:

    (1)su UserName

    (2)图形界面下打开的终端

    (3)执行脚本

    (4)任何其它的bash实例

    执行顺序: ~/.bashrc --> /etc/bashrc -->/etc/profile.d/*.sh

    配置文件的两种分类

    按功能划分,存在两类:profile类和bashrc

    profile类:为交互式登录的shell提供配置

    全局: /etc/profile, /etc/profile.d/*.sh

    个人: ~/.bash_profile

    功用:

    (1) 用于定义环境变量

    (2) 运行命令或脚本

    bashrc类:为非交互式和交互式登录的shell提供配置

    全局: /etc/bashrc

    个人: ~/.bashrc

    功用:

    (1) 定义命令别名和函数

    (2) 定义本地变量

    编辑配置文件生效

    修改profilebashrc文件后需生效

    两种方法:

    1重新启动shell进程

    2 . source

    :

    . ~/.bashrc

    Bash退出任务

    保存在~/.bash_logout文件中(用户)

    在退出登录shell时运行

    用于

    创建自动备份

    清除临时文件

    关于$-变量

    h hashall,打开这个选项后, Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +hh选项关闭

    i interactive-comments,包含这个选项说明当前的 shell是一个交互式的 shell。所谓的交互式shell,在脚本中, i选项是关闭的。

    m monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等。

    B braceexpand,大括号扩展

    H history H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令

    [root@CT6 tmp]# echo $-
    himBH
    [root@CT6 tmp]# set +h
    [root@CT6 tmp]# echo $-
    imBH
    [root@CT6 tmp]# set +B
    [root@CT6 tmp]# echo $-
    imH

     

     

  • 相关阅读:
    C++:随机数生成
    C++:typedef 与 #define 的区别
    读书笔记
    从零开始:Spring Security Oauth2 讲解及实战
    SpingCloud:Gateway+Nginx+Stomp+Minio构建聊天室并进行文件传输
    Docker image-Ubuntu(jessie)下postgresql-client安装方法
    7张图了解kafka基本概念
    打包上传python代码到pypi,通过pip安装使用
    Asp.Net Core 中的HTTP协议详解
    LeetCode 1931. Painting a Grid With Three Different Colors(DP)
  • 原文地址:https://www.cnblogs.com/duzhaoqi/p/7308814.html
Copyright © 2011-2022 走看看