linux bash算术运算和条件语句

+, -, *(乘), /(除), **(乘方), %(取模)

  • let var=算术运算符表达式

    高级let用法:let i+=2

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

    自增:let var++

  • var=$[算术运算符表达式]

  • var=$((算术运算符表达式))

  • var=$(expr $ARG1 OP $APG2)

</font color=red>注意:乘法符号在某些场景中需要使用转义符

练习1:写一个脚本文件,完成如下功能:添加3个用户,求这3个用户的UID之和。

#!/bin/bashid testUser1 > /dev/null || useradd testUser1id testUser2 > /dev/null || useradd testUser2id testUser3 > /dev/null || useradd testUser3uid1=`grep "testUser1" /etc/passwd | cut -d: -f3`uid2=`grep "testUser2" /etc/passwd | cut -d: -f3`uid3=$(grep "testUser3" /etc/passwd | cut -d: -f3)#方法1#let num=$uid1+$uid2+$uid3#方法2#num=$[$uid1+$uid2+$uid3]#方法3num=$(($uid1+$uid2+$uid3))#方法4#num=$(expr $uid1 + $uid2 + $uid3)echo $num

练习2:写一个脚本文件,完成如下功能:求/etc/passwd文件中第10行和第20行的用户的UID之和

#!/bin/bash#先用head取前10行,再用tail取最好一行,然后再用cut切la=`head -10 /etc/passwd | tail -1 | cut -d: -f3`lb=`head -20 /etc/passwd | tail -1 | cut -d: -f3`echo $laecho $lblet lc=$la+$lbecho $lc

练习3:写一个脚本文件,完成如下功能:求/etc/passwd文件中,uid最大的2个uid之和

#!/bin/bash#先用冒号把文件分成多列,用第三列从大到小排序后,分别取第一行和第二行,最后在用cut切开la=`sort -t: -k3 -nr /etc/passwd | head -1 | cut -d: -f3`lb=`sort -t: -k3 -nr /etc/passwd | head -2 | tail -1 | cut -d: -f3`echo $laecho $lblet lc=$la+lbecho $lc

练习4:写一个脚本文件,完成如下功能:通知2个文件里的空白行数之和

#!/bin/bash#用grep找出空白行(使用正则表达式),然后再用wc数一数有多少行la=`grep -e "^[[:space:]]*$" /etc/rc.d/init.d/functions | wc -l`lb=`grep -e "^[[:space:]]*$" /etc/inittab | wc -l`echo $laecho $lblet lc=$la+$lbecho $lc

条件语句

测试表达式:

  • test expression

  • [ expression ]

  • [[ expression ]]

注意:中括号中间的空格,没有空格就是语法错误

bash的条件测试类型

  • 数值比较大小

    例子:[ 2 -ne 3 ]和test 2 -ne 3效果一样

    #!/bin/bashif [ 2 -ne 3 ]; then    echo 11else    echo 22fiif test 2 -ne 3; then    echo 111else    echo 222fi
    • -eq:等于 [ $num1 -eq $num2 ]

    • -ne:不等于[ $num1 -ne $num2 ]

    • -gt:大于[ $num1 -gt $num2 ]

    • -ge:大于等于[ $num1 -ge $num2 ]

    • -lt:小于[ $num1 -lt $num2 ]

    • -le:小于等于[ $num1 -le $num2 ]

  • 字符串比较

    == :等于

    > :大于

    < :小于

    != :不等于

    =~ :左侧字符串是否被右侧的正则表达式所匹配。

    -z "STRING" :指定字符串为空则为真

    -n "STRING":指定字符串不为空则为真

    做字符串比较的变量,最好加上“”。不加的话,如果做比较的某个变量没有被定义的话,执行就会出错。

    下面的例子,tom是不存在的变量,不加括号就出错误了,加了就没有错误。

    $ [ tom = $tom ]-bash: [: tom: unary operator expected$ [ tom = "$tom" ]$ echo $?1

    字符串比较,最好要用[[]]。

    下面的例子,说明了用[]无法比较

    $ [ a > b ]$ echo $?0$ [ a < b ]$ echo $?0$ [ "a" < "b" ]$ echo $?0$ [ "a" > "b" ]$ echo $?0

    下面的例子,说明用[[ ]]达到了预期。

    $ [[ a < b ]]$ echo $?0$ [[ a > b ]]$ echo $?1$ [[ "a" > "b" ]]$ echo $?1$ [[ "a" < "b" ]]$ echo $?0

    字符串空的判断:

    $ [[ -z "$tom" ]]$ echo $?1[ys@localhost ~]$ [[ -n "$tom" ]][ys@localhost ~]$ echo $?

    正则表达式的匹配:

    $ tom=ooo[ys@localhost ~]$ [[ $tom =~ o.* ]][ys@localhost ~]$ echo $?0[ys@localhost ~]$ tom=jerry[ys@localhost ~]$ [[ $tom =~ o.* ]][ys@localhost ~]$ echo $?1
  • 文件测试

    • 文件存在性检查:-a FILE,或者,-e FILE。存在返回0.

      例子:[ -a /etc/passwd ][ -e /etc/passwd ]

    • 文件存在性和类型检查

      -b FILE:文件存在,且类型是块设备,则返回0.

      -c FILE:文件存在,且类型是字符设备,则返回0.

      -d FILE:文件存在,且类型是目录,则返回0.

      -f FILE:文件存在,且类型是普通文件,则返回0.

      -h或 -L FILE:文件存在,且类型是符号链接,则返回0.

      -p FILE:文件存在,且类型是命名管道,则返回0.

      -S FILE:文件存在,且类型是本地套接字,则返回0.

      $ [ -b /dev/sda ][ys@localhost scripts]$ echo $?0[ys@localhost scripts]$ [ -b /dev/sdad ][ys@localhost scripts]$ echo $?1[ys@localhost scripts]$ [ -b 2.sh ][ys@localhost scripts]$ echo $?1
    • 文件权限检查

      -r FILE:文件存在,且当前用户(运行此shell进程的用户)可读,则返回0.

      -w FILE:文件存在,且当前用户(运行此shell进程的用户)可写,则返回0.

      -x FILE:文件存在,且当前用户(运行此shell进程的用户)可执行,则返回0.

    • 特殊权限检查

      -u FILE:文件存在,且拥有suid权限,则返回0.

      -g FILE:文件存在,且拥有sgid权限,则返回0.

      -k FILE:文件存在,且拥有sticky权限,则返回0.

    • 文件是否有内容

      -s FILE:文件存在,且有内容,则返回0

    • 时间戳

      -N FILE:文件自从上一次读取操作后,是否被修改过。

    • 从属关系

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

      -G FILE:当前用户是否在文件属组里。

    • 双目

      FILE1 -ef FILE2:如果FILE1和FILE2是指向同一个文件系统的相同inode的硬链接,则返回0.

      FILE1 -nt FILE2:如果FILE1的修改时间戳新于FILE,则返回0

      FILE 1 -ot FILE2:如果FILE1的修改时间戳旧于FILE,则返回0

组合测试条件

第一种方式:

  • [ expression1 ] && [ expression2 ]

  • [ expression1 ] || [ expression2 ]

  • ! COMMOND

第二种方式:

  • 与运算:[ expression1 -a expression2 ]

  • 或运算:[ expression1 -o expression2 ]

练习:判断主机名称是否为空,或者是否是localhost.localdomain

#!/bin/bashhostname=`hostname`if [ -z "$hostname" -o "$hostname" == "localhost.localdomain" ]; then    hostname=11111else    echo "ng"fiecho $hostname

向脚本文件传递执行时候的参数

使用位置参数变量:$1,$2,...${10},${11}.

10之后的参数必须加上{}。

$0:是脚本本身的路径加脚本文件的名字。

$#:是参数的个数

$*:拿到所有参数。但把所有参数汇总成了一个串

$@:拿到所有参数。但没有把参数汇总成一个串。

当执行下面命令后,$1的值就是111;$2的值就是222;$3的值就是333;

$ ./script.sh 111 222 333

shift用法:shift n:踢掉前n个位置参数变量

下面的内容保存在shift.sh中

#!/bin/bashecho $1 $2shift 1echo $1shift 1echo $1

执行shift.sh的结果:

# bash shift.sh 111 222 333111 222222333

练习:传递2个文本文件的路径给脚本,计算出空白行数之和。

#!/bin/bashla=`grep -e "^[[:space:]]*$" $1 | wc -l`lb=`grep -e "^[[:space:]]*$" $2 | wc -l`echo $laecho $lblet lc=$la+$lbecho $lc

执行结果:

# bash sumforarg.sh /etc/rc.d/init.d/functions /etc/inittab91091

if语法

if  con1 ; thenelif con2 ; thenelsefi

练习:查看给定用户是否存在,不存在则创建此用户。

#!/bin/bashif ! grep "^$1\>" /etc/passwd &> /dev/null ; then    useradd $1    # 设定用户$1的密码是111    echo "111" | passwd --stdin $1 &> /dev/null    echo "add user $1 donw!"fi

练习:比较2个数字的大小

#!/bin/bash#声明一个变量,是整数。declare -i max#参数个数小于2if [ $# -lt 2 ]; then    echo "at least one argu"    exit 1fi#参数1大于参数2if [ $1 -ge $2 ]; then    max=$1else    max=$2fiecho "max number is $max"

练习:判断给定用户名的id号是奇数还是偶数

#!/bin/bashif [ $# -lt 1 ]; then    echo "at least one argu"    exit 1fi#取得用户的iduid=$(grep "^$1\>" /etc/passwd | cut -d: -f3)echo $uid#判断奇偶数if [ $[$uid % 2] -eq 0 ]; then    echo "oushu"else    echo "jishu"fi

运行结果:

# bash jigou.sh ys1000oushu# bash jigou.sh fedora1005jishu

练习:给2个文本文件路径,如果文件不存在,则结束脚本;都存在则返回每个文件的行数,并找出行数多的文件

#!/bin/bashif [ $# -lt 2 ]; then    echo "at least two argu"    exit 1fiif ! [ -e $1 -a -e $2 ]; then    exit 1else    la=`wc -l < $1`    lb=`wc -l < $2`    echo "$1 行数:$la;$2 行数:$lb"    if [ $la -ge $lb ]; then        echo "$1 行数多"    else        echo "$2 行数多"    fifi

运行结果:

# bash sum1.sh /etc/passwd /etc/fstab/etc/passwd 行数:56;/etc/fstab 行数:13/etc/passwd 行数多

case语法

case $var in    pat1)        ;;    pat2)        ;;    pat3)        ;;    *)        ;;esac

pat支持globbing风格:

  • *:匹配任意长度的任意字符

  • ?:匹配任意单个字符

  • []:匹配指定范围内的任意单个字符

  • [^]:匹配指定范围外的任意单个字符

  • {}:表示符合括号内包含的多个文件

  • aaa|bbb:aaa或bbb

执行完脚本文件后,返回值是啥?

默认是脚本文件里最后一条命令的返回值。

可以自定义返回值:使用exit n命令,n为数字。

当shell进程遇到exit命令时,进程会立即终止,因此exit后面的命令就不执行了。

(0)

相关推荐

  • Linux学习笔记(一)——Shell

    Shell概述 1. Shell是什么 l Shell是一个命令行解释器,它为用户提供了一个向Linux内核发送请求以便运行程序的界面系统级程序,用户可以用Shell来启动.挂起.停止甚至是编写一些程 ...

  • PHP实现上传文件并存进数据库的方法

    本文实例讲述了PHP实现上传文件并存进数据库的方法.分享给大家供大家参考.具体如下: show_add.php文件如下: <?php if(!isset($_REQUEST['id']) or ...

  • 用户的管理

    用户组及配置文件 用户的类型 Linux是一个多用户.多任务的操作系统,如果要使用系统资源,就必须向系统管理员申请一个用户,通过这个用户进入系统,通过建立不同属性的用户实现 不同的作用或权限,可以合理 ...

  • 【原创教程】houdini17 vex if条件语句完全讲解第一集

    --  微资讯 · 微课程  -- 利用零碎时间,走上超神之路! 教程编号 CGhunter_houdini_04_006_002 if statement1(vex字典卷第6章if条件语句完全讲解第 ...

  • linux shell 算术运算{expr、bc、dc、(( ))和[ ]}

    linux shell 算术运算{expr、bc、dc、(( ))和[ ]}

  • 细说AppInventor【68】条件语句

    知识点:①流程图 ②条件语句 老巫婆书店 纠错:流程图中,当条件不成立时,应该执行分支2,现在图中的两个分支都是分支1.

  • Python教程:Python的条件语句

    上次我们学习了关于Python的运算符的知识,这次我们来学习Python的条件语句.python的条件语句是一种选择结构,因为它是通过if关键字实现的,因此也称为if语句.(与C和Java不同,pyt ...

  • Java基础之条件语句

    先来个冷笑话吧:某程序员的老婆叫他上街买几个桃子,吩咐如果有西瓜,买一个.后来他就真的只买了一个桃子回来. 说这个是笑话的人,我看他是不知道条件语句,反正我觉得这个程序员做得对,哈哈哈. if语句 i ...

  • Python 条件语句 | 菜鸟教程

    Python 条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块. 可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何非0和 ...

  • Python教程-Python条件语句

    Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执行的代码块.可以通过下图来简单了解条件语句的执行过程: Python程序语言指定任何非0和非空(null)值为tru ...

  • 一文讲解Python条件语句的使用方法

    Python条件语句是由执行一条或多条语句的结果(True或False)来决定要执行的代码块.Python程序语言指定true和非空(null)值均为true,0或null为false. Python ...

  • Python条件语句之关于input的使用

    因为条件语句比较简单,开始学习条件语句不需要很长时间的学习.所以在学习input()可以编写一些有趣的小程序,可以打发时间. 条件语句 条件语句时通过一条或者多条条件语句代码执行的结果是True还是F ...