shell脚本进阶

Posted 绮梦小煊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell脚本进阶相关的知识,希望对你有一定的参考价值。

一、逻辑运算

变量:

  本地变量、环境变量、局部变量、位置参数变量、特殊变量

  变量赋值:name=value,export name=value,declare -x name=value

  变量引用:$name,${name}

  注意:有些时候{}不能省略,例如

       echo "$valuemagedu.com" 

       echo "${value}magedu.com"

   撤销:unset name

bash脚本编程,运行脚本

#!/bin/bash      #称为shebang是bash脚本的默认开头行固定格式

#             #   #号后面是注释信息,不显示也不影响脚本执行结果

空白行          忽略不显示行

bash的配置文件

porfile类:登录式shell

bashrc类:非登录式shell

登录式shell:/etc/profile–>/etc/profile.d/*.sh–>~/.bash_profile–>~/.bashrc–>/etc/bashrc

非登录式shell:~/.bashrc–>/etc/bashrc–>/etc/profile.d/*.sh

    

算数运算

   +,-,*,/,**(乘次方),%(求模取余)

在bash中默认数据类型都是字符串形式,做算数运行需要经特殊方法才可以

示例:     

[[email protected] ~]# num1=2
[[email protected] ~]# num2=9
[[email protected] ~]# echo "${num1}+${num2}"
2+9
[[email protected] ~]# declare -i num3=5
[[email protected] ~]# declare -i num4=9
[[email protected] ~]# echo "${num3}+${num4}"
5+9

算术运算格式:

(1)let VAR=算数运算表达式

[[email protected] ~]# let ${num1}+${num2}

#默认不输出结果到屏幕,所以需要赋值给变量,再引用

[[email protected] ~]# let sum5=${num1}+${num2}
[[email protected] ~]# echo ${sum5}
11

let 参数 [参数 …]

   算术运算格式含义

    num++,num– (两个减号不是大横线)变量后递增,后递减

     ++num,–num(两个减号不是大横线)变量前递增,前递减

     +,-加法、 减法

     !,~ 逻辑和按位求反

     ** 求幂运算(乘次方)

     *,/,%  乘法,除法,求模(求余)           

     <<,>> 左和右移位

     <=,>=,<,> 比较

      ==、 != 平等,不平等

      & 按位与

     ^ 按位异或

     | 按位或

      && 逻辑与

      || 逻辑或

      expr ?expr: expr

条件运算符

       =, *=, /=, %=,+=, -=, <<=, >>=,&=,^=,|= 赋值

变量也可以作为let 命令的参数              

(2)VAR=$[算数运算表达式]   

但是不能直接运行,赋不赋值给变量都可以,需要命令直接引用,如echo

[[email protected] ~]# $[${num2}+${num3}]
bash: 14: 未找到命令...
[[email protected] ~]# echo "$[${num2}+${num3}]"
14

(3)VAR=$((算数运算表达式))  

但是不能直接运行,赋不赋值给变量都可以,需要命令直接引用,如echo

[[email protected] ~]# $((${num2}+${num3}))
bash: 14: 未找到命令...
[[email protected] ~]# echo $((${num2}+${num3}))
14

(4)expr EXPRESSION 或 VAR=$(expr EXPRESSION)

  expr OPTION

示例:

[[email protected] ~]# num1=2
[[email protected] ~]# num2=4
[[email protected] ~]# expr ${num1} + ${num2}
6
[[email protected] ~]# sum=$(expr ${num1} \* ${num2})
#注意乘法*符号需要转意(原因是*号在有些场景中为glob通配符)
[[email protected] ~]# echo "${sum}"
8

expr 参数的算术运算格式

                ARG1 | ARG2

                ARG1 是否为 null,也不是 0,否则为 ARG2

                ARG1 & ARG2

                ARG1 如果参数都不是 null 或 0,否则为 0

                ARG1 < ARG2

                ARG1 小于 ARG2

                ARG1 <= ARG2

                ARG1 小于或等于 ARG2

                ARG1 = ARG2

                ARG1 等于 ARG2

                ARG1 != ARG2

                ARG1 ARG2 不等于

                ARG1 >= ARG2

                ARG1 是大于或等于 ARG2

                ARG1 > ARG2

                ARG1 大于 ARG2

                ARG1 + ARG2

                ARG1 和 ARG2 的算术总和

                ARG1 -ARG2

                ARG1 减 ARG2 的算术差

                ARG1 * ARG2

                ARG1 和 ARG2 的算术积

                ARG1 / ARG2

                ARG1 除以 ARG2 的算术商

                ARG1 % ARG2

                ARG1 除以 ARG2 的算术余数

注意:算数运算格式内各参数彼此之间必须有空格,并且shell脚本不支持浮点型

增强型赋值:

       变量做某种算数运算后回存至此变量中;

            eg:  

               let i=$i+#

               let i+=#

            还有:+=,-=,*=,/=,%=

            自增:

                 VAR=$[$VAR+1]

                 let VAR+=1  

                 let VAR++

            自减:

                 VAR=$[$VAR-1]

                 let VAR-=1

                 let VAR–

         

二、条件测试:

     判断某需求是否满足,需要由测试机制来实现;

     如何编写测试表达式以实现所需的测试;

       (1)执行命令,并利用命令状态返回值来判断

          0:成功

          1-255:失败

       (2)测试表达式

           test EXPRESSION   eg:test 3 -gt 2

            [ EXPRESSION ]

            [[ EXPRESSION ]]

        注意:EXPRESSION两端必须有空白字符,否则有语法错误

bash的测试类型:

          数值测试:数值比较

                 -eq:是否等于;     eg:[ $num1 -eq $sum2 ]

                 -ne:是否不等于

                 -gt:是否大于

                 -ge:是否大于等于

                 -lt:是否小于

                 -le:是否小于等于

          字符串测试:

              ==:是否等于;(字符串)

一个=号也可以由于赋值变量用=号,但是赋值并不应用到[]中,所以能够使用,但是还是推荐使用双=号

              >:是否大于

              <:是否小于

             !=:是否不等于

             =~:左侧字符串时候能够被右侧的PATTERN所匹配;(模糊匹配而非精确匹配) 

示例:

[[email protected] ~]# [[ tom =~ tom ]]
[[email protected] ~]# echo $?
0
[[email protected] ~]# [[ tom =~ om ]]
[[email protected] ~]# echo $?
0
[[email protected] ~]# [[ tom =~ o ]]
[[email protected] ~]# echo $?
0
[[email protected] ~]# [[ tom =~ x ]]
[[email protected] ~]# echo $?
1

-z "STRING":判断指定的字符串是否为空,空为真,不空为假

-n "STRING":判断指定的字符串是否为不空,不空为真,空为假  

注意:(1)字符串测试时:字符串要加引号,表示引用有变量命令"",没有变量命令使用‘‘

    (2)作比较时,尽量使用[[]];

   (3) 但是在组合测试时,[[]]有时会有语法错误,所以可以使用[]

示例:

[[email protected] ~]# [ var1 == var1 ]
[[email protected] ~]# echo $?
0
[[email protected] ~]# [ var1 == Var1 ]
[[email protected] ~]# echo $?
1
[[email protected] ~]# [ var1 == ${Var2} ]
-bash: [: var1: 期待一元表达式
[[email protected] ~]# [ var1 == "${Var2}" ]
[[email protected] ~]# echo $?
1
[[email protected] ~]# [ a > b]
-bash: [: 缺少 `]‘
[[email protected] ~]# [ a > b ]
[[email protected] ~]# echo $?
0
[[email protected] ~]# [ a < b ]
[[email protected] ~]# echo $?
0
[[email protected] ~]# [ "a" < "b" ]
[[email protected] ~]# echo $?
0
[[email protected] ~]# [ "a" > "b" ]
[[email protected] ~]# echo $?
0
[[email protected] ~]# [[ "a" > "b" ]]
[[email protected] ~]# echo $?
1

文件测试:

     存在性测试:

            -a FILE  少使用

            -e FILE 推荐使用

文件存在则为真,否则为假  

存在性及类型测试:

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

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

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

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

            -h FILE 或 -L FILE:是否存在并且为符号链接文件;

            -p FILE:是否存在并且为管道文件;

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

文件权限测试:

            -r FILE:是否存在并且对当前用户可读;

            -w FILE:是否存在并且对当前用户可写;

            -x FILE:是否存在并且对当前用户可执行;

特殊权限测试:

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

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

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

注意:对于脚本则是当前运行此脚本的用户

文件是否有内容:

          -s FILE:是否有内容;

时间戳测试:

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

从属关系测试:

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

       -G FILE:当前用户是否属于文件的属组;

双目测试:

     FILE 1 -ef FILE2 :FILE1与FILE2是否指向同一个文件系统的相同inode的硬链接;

     FILE 1 -nt FILE2 :FILE1的最近一次更新时间是否新于FILE2的最近一次更新时间

     FILE 1 -ot FILE2 :FILE1的最近一次更新时间是否旧于FILE2的最近一次更新时间

组合测试条件:

       逻辑运算:

       第一种方式:

             COMMAND1 && COMMAND2

             COMMAND1 || COMMAND2

             ! COMMAND

            eg: [ -O FILE ] && [ -r FILE ]

       第二种方式:

            test EXPRESSION1 -a EXPRESSION2

            [ EXPRESSION1 -a EXPRESSION2 ]

            [[ EXPRESSION1 -a EXPRESSION2 ]]

类此还有

     EXPRESSION1 -o EXPRESSION2

     ! EXPRESSION

eg:[ -O FILE -a -r FILE ]

注意:模式匹配时,势必要激活正则表达式引擎,而使用正则表达式的测试判断,要比单一字符串测试判断要慢,所以尽量避免使用正则表达式进行查找比较和测试;

脚本的状态返回值:

           默认是脚本中执行的最后一条件命令的状态返回值

           自定义状态退出状态码:exit [n]:n为自己指定的状态码;

       注意:shell进程遇到exit时,即会终止,因此,整个脚本执行即为结束;

 

三、bash脚本语句

过程式编程语言的代码执行顺序:

           顺序执行:从左至右,从上至下,逐一运行

           选择执行:代码有一个分支:条件满足时才会执行

                 两个或以上的分支:只会执行其中一个满足条件的分支

           循环执行:

                 代码片段(循环体)要执行0、1或多次重复运行

选择执行:

     单分支的if语句

    if 测试条件;then 

      代码分支 

      条件为真则执行,为假则不执行

或者

    fi       

    if 测试条件      

     then      

        代码分支                                     

        条件为真则执行,为假则不执行                                        fi                            

双分支的if语句:

         if 测试条件;then

           条件为真时执行的分支

         else

           条件为假时执行的分支

         fi

多分支的if语句:

          if COMDITION1;then

            条件1为真分支

          elif COMDITION2;then

              条件2为真分支

          elif COMDITION3;then

             条件3为真分支

          …

          elif COMDITIONn;then

             条件n为真分支

          else

             所有条件均不满足时的分支

          fi

注意:即便多个条件可能同时都能满足,分支只会执行其中一个,首先测试为“真”;并且if语句可嵌套if等其他语句

case语句的语法格式:

    case $VARAIBLE in

    PATH1)

          分支

          ;;

    PATH2)

          分支

          ;;

    …

    *)

          分支

          ;;

    esac

    注意:双分号如果不加,则会前一个匹配执行后,下一个会接着匹配执行

          适用于一个变量,与多个可能取值比较

          支持glob风格的通配符:

                         *:任意长度的任意字符;

                         ?:任意单个字符

                         []:范围内任意个字符

                         a|b:a或b;

bash脚本编程之用户交互:

    脚本参数

       用户交互:通过键盘输入数据,从而完成变量赋值操作

           read [option]…[name…]

                  -p ‘PROMPT‘    提示注释信息

                  -t TIMEOUT     时间限制

       bash -n /path/to/some_script

               检测脚本中的语法错误

       bash -x /path/to/some_script

               调试执行

 

循环执行:将一段代码重复执行0、1或多次;

     进入条件:条件满足时才进入循环

     退出条件:每一个循环都应该有退出条件,以有机会退出循环

bash脚本:

     for循环

     while循环

     until循环

for循环:

       执行机制:依次将列表中的元素赋值给“变量名” ; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束

   两种格式:

     (1)遍历列表

     (2)控制变量

    遍历列表

        for VARAIBLE in LIST;do

             循环体

        done

    进入条件:LIST列表有元素,即可进入循环

    退出条件:列表中的元素遍历完成

 

    LIST的生成方式:

         (1)直接给出;

         (2)整数列表

                  (a){start…end}

                  (b)seq [start [incremtal]] last

          (3)返回列表的命令:$(COMMAND),例如:ls  cat

         (4)glob通配符

         (5)变量引用;例如[email protected],$*

    格式示例:

    #!/bin/bash

    #

    for username in user1 user2 user3;do

        if id $username &>/dev/null;then

           echo "$username exists."

        else

           useradd $username && echo "Add user $username finished."

        fi

    done

 

    示例:求100以内的正整数之和

    #!/bin/bash

    #

    delcare -i sum=0

    for i in {1..100};do

        echo "\$sum is $sum,\$i is $i"

        sum=$[$sum+$i]

    done

    echo $sum

 

    示例:判断/var/logm目录下的每一个文件的内容类型

    #!/bin/bash

    #

    for filename in /var/log/*;do

    if [ -f $filename ];then

       echo "Common file."

    elif [ -L $filename ];then

       echo "Sysbolic link"

    elif [ -d $filename ];then

       echo "Directory."

    elif [ -b $filename ];then

       echo "block special file."

    elif [ -c $filename ];then

       echo "character special file."

    elif [ -S $filename ];then

       echo "Socket file."

    else

       echo "Unkown."

    fi

    done

 

while循环:

     while CONDITION;do

           循环体

           循环控制变量修正表达式

     done

     

     CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正

 

     进入条件:CONDITION测试为“真”

     退出条件:CONDITION测试为“假”

     示例:求100以内的正整数之和

     #!/bin/bash

     #

     declare -i sum=0

     declare -i i=1

     while [ $i -le 100 ];do

          sum=$[$sum+$i]

          let i++

     done

     echo $sum

 

 

1、编写脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;显示添加的用户的id号等信息

#!/bin/bash
#写一个脚本/root/bin/createuser.sh,实现如下功能:使用一个用户名做为参数,如果指定参数的用户存
在,就显示其存在,否则添加之;显示添加的用户的id 号等信息
[[ -z $1 ]] && echo "请输入一段字符串作为用户名"&& exit
if grep -E "^$1:" /etc/passwd &>/dev/null;then
     echo "s1:已经存在此用户"
     exit
else
     useradd $1
     id $1
     echo "用户已经帮您添加"
     exit
fi

2、编写脚本/root/bin/yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes还是no,或是其它信息

#!/bin/bash
#提示用户输入yes或no, 并判断用户输入的是yes 还是no,或是其它信息
[[ -z $1 ]] && echo "请输入一段字符串" && exit
var=`echo "$1" tr "[[:lower:]]" "[[:upper:]]"
if [[ ${var} =~ "YES" ]];then
     echo "用户输入的是$1"
elif [[ ${var} =~ "NO" ]];then
     echo "用户输入的是$1"
else
     echo "用户输入的是其它信息"
fi
unset var

3、编写脚本/root/bin/filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,链接,其它文件类型)

#!/bin/bash
if [[ $# -lt 1 ]]
then
    echo -e "Error: No argument.\n\tUsage: $0 FILENAME"
    exit 1
else
    if [[ ! -e $1 ]]
    then
        echo "$1: No such file or diretory"
    elif [[ -d $1 ]]
    then
        echo "$1 is a diretory"
    elif [[ -L $1 ]]
    then
        echo "$1 is a link file"
    elif [[ -f $1 ]]
    then
        echo "$1 is a common file"
    fi
fi

4、编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

#!/bin/bash
read -p "请入一个数字:" num
[ -z "$num" ]&&echo "请输入一个数字"&&exit 1
NUM=$(echo $num |grep -Eo "\-?[[:digit:]]+")
if "$NUM" == "$num" ];then
         if "$NUM" -lt "0" ];then
                echo "您输入的是一个负整数!"
        elif "$NUM" -eq "0" ];then
                echo "您输入的是一个0!"
        else
                echo "恭喜,您输入的是一个正整数!"
        fi
else
        echo "您输入的不是一个整数,请重新运行脚本!"
fi

练习:用for实现
1、判断/var/目录下所有文件的类型

#!/bin/bash
cd $1 &> /dev/null
# diretory judge
if [[ $? = 0 ]]
then
 
    for in `ls -A $1`
    do
        FileType=`ls -dl $DirName/$i | cut -c1`
        case $FileType in
            d)
                echo "$i is a diretory."
                ;;
            -)
                echo "$i is a common file."
                ;;
            l)
                echo "$i is a link file."
                ;;
            b)
                echo "$i is a block file."
                ;;
            c)
                echo "$i is a character file."
                ;;
            p)
                echo "$i is a pipe file."
                ;;
            s)
                echo "$i is a socket file."
                ;;
            *)
                echo "$i is other file"
                ;;
        esac
    done
else
    echo "$1 is not a diretory"
    exit 2
fi
 
 
unset DirName
unset FileType

2、 添加10个用户user1-user10,密码同用户名

#/bin/bash
if [[ $# -lt 1 ]]
then
    echo -e "Error: No option \n\t-d\tdelete user1-user10\n\t-a\tadd user1-user10 "
    exit 1
fi
 
for in $(seq 10);do
    case $1 in 
        -d|--del)
            if id user$i &> /dev/null;then
                userdel -r user$i
                echo "user$i: Delete complete!"
            else
                echo "user$i: No such user!"
            fi
            ;;
        -a|--add)
            if id user$i &> /dev/null;then
                echo "user$i"passwd --stdin "user$i" &> /dev/null
                echo -e  "user$i: Already existed!\nAnd authentication tokens updated successful!"
            else
                useradd user$i &> /dev/null
                echo "user$i"passwd --stdin "user$i" &> /dev/null
                echo " user$i: Add complete!"
            fi
            ;;
        *)
            echo "Error:"
            echo -e "$0 : Unknow option!\nplease use ‘-a‘‘--add‘ to add user or ‘-d‘‘--dell‘to delect user"
            exit 1
            ;;
    esac
done

3、 /etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的文件输出为文件加stop,以S开头的文件输出为文件名加start;
“ K34filename stop”
“S66filename start”

#!/bin/bash
for in `ls /etc/rc.d/rc3.d`
do
    FileC1=`echo $i | cut -c1`
    case $FileC1 in
        K)
            echo -e "$i\tstop"
            ;;
        S)
            echo -e "$i\tstart"
            ;;
        *)
            echo "unkown file"
            ;;
    esac
done

4、编写脚本,提示输入正整数n的值,计算1+2+3+…n的总和

#!/bin/bash
#
    delcare -i sum=0
    for in {1..$1};do
        echo "\$sum is $sum,\$i is $i"
        sum=$[$sum+$i]
    done
    echo $sum

5、编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态

#!/bin/bash
# 写一个脚本,提示请输入网络地址,如 192.168.0.0 ,判断输入的网段中主机在线状态
 
# only for netmask 255.255.255.0
echo -n "Enter IP:"
read IP
#get IP segment
Segment=`echo $IP | cut -d. -f1-3 `.
#
if echo $IP | egrep ‘\<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){2}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\>‘ &>/dev/null
then
    #test only  5 host
    for in `seq 240 255`
    do
        if ping -c 1 -W 1 $Segment$i &> /dev/null
        then
            echo -e "$Segment$i\tonline"
        else
            echo -e "$Segment$i\toffline"
        fi
    done
else
    echo "$IP is invalid"
fi

6、 打印九九乘法表

#!/bin/bash
#
for in {1..9};do
    for in $(seq 1 $i);do
        echo -n -e "$j*$i=$[$j*$i]\t"
    done
        echo
done

 

用while实现
1、 编写脚本,求100以内所有正整数之和

#!/bin/bash
#
     declare -i sum=0
     declare -i i=1
     while [ $i -le 100 ];do
          sum=$[$sum+$i]
          let i++
     done
     echo $sum

2、 编写脚本,通过ping命令探测172.16.250.1-254范围内的所有主机的在线状态,统计在线主机和离线主机各多少。

#!/bin/bash
#
a="10.1.252."
i=0
j=0
k=0
while [ $i -le 255 ];do
    ping -c1 -W1 $a$i &> /dev/null
    if [ $? -eq 0 ];then
        echo "$a$i is active"
         
        let j++
    else
        echo "$a$i is inactive"
        let k++
    fi
    let i++
done
echo "the sum number of active users is $j"
echo "the sum number of inactive users is $k"

3、 编写脚本,打印九九乘法表

#!/bin/bash
#function: 9*9 tables
#author: xiaoshui
i=1
while [ $i -le 9 ];do
    j=1
    while [ $j -le $i ];do
        mul=$[$i*$j]
        echo -ne "$i*$j=$mul\t"
        j=$[$j+1]
    done
    echo 
    i=$[$i+1]
done

4、 编写脚本,利用变量RANDOM生成10个随机数字,输出这个10数字,并显示其中的最大者和最小者

#!/bin/bash
#
i=10
a=$RANDOM
max=$a
min=$a
while [ $i -ge 1 ]
do
    [ $max -lt $a ] && max=$a
    [ $min -gt $a ] && min=$a
    echo "$a"
    a=$RANDOM
    let i--
done
echo "最大值$max"
echo "最小值$min"

5、编写脚本,实现打印国际象棋棋盘

#!/bin/bash
#
#
#
i=1
 
while [ $i -le 8 ];do
    j=1
    while [ $j -le 8 ];do
        sum=`expr $i + $j`
        z=`expr $sum % 2`
        [ $z -eq 0 ] && echo -ne "\033[41;1m  \033[0m"||echo -ne "\033[43;1m  \033[0m"
        let j++
    done
    echo
    let i++
done
#!/bin/bash
#
declare -i i=1
declare -i j=1
while [ $i -lt 9 ];do
    if [ $[$i%2] -eq 0 ] ;then
         while [ $j -lt 9 ];do
                    if [ $[$j%2] -ne 0 ];then
                            echo -en "\e[43;37m  \e[0m"
                    else
                            echo -en "\e[45;37m  \e[0m"
                    fi
                    let j++
            done
    else 
        while [ $j -lt 9 ];do
            if [ $[$j%2] -eq 0 ];then 
                echo -en "\e[43;37m  \e[0m"
            else 
                echo -en "\e[45;37m  \e[0m"
            fi
            let j++
        done
        fi
    declare -i j=1
    let i++
    echo ""
done   
unset i;unset j

1、每隔3秒钟到系统上获取已经登录的用户的信息;如果发现用户hacker登录,则将登录时间和主机记录于日志/var/log/login.log中,并提示该用户退出系统。

#!/bin/bash
#function: check hacker login and hint logout
until who |grep -q "^hacker\b" ;do
    sleep 3
done
who grep "^hacker"|tr -s ‘ ‘|cut -d‘ ‘ -f3,5 >> /var/log/login.log
echo "you should logout system" | mail hacker
echo "reminded and login record in /var/log/login.log"   

2、随机生成10以内的数字,实现猜字游戏,提示比较大或小,相等则退出。

#!/bin/bash
suiji=$[$RANDOM%10+1]
read -p "请输入数字:" num
until [[ $suiji -eq $num ]]; do
    [ $shuru -lt $suiji ] && echo "小了,往大了猜" 
    [ $shuru -gt $suiji ] && echo "大了,往小了猜"
    read -p "请再次输入数字:" num
done
echo "恭喜你猜中了!!!"

1、写个脚本:

   *
  ****
 ********
************

1 4

1,3空格1个*

2,2空格2个*

3,1空格,3*

 

n行空格数=总行数-n

n行*数=2n-1

#!/bin/bash
#
#打印三角形
#获取终端宽度
termCols=`tput cols`
 
#根据终端宽度,判断出能够正常打印三角形的行数;
maxLineNum=`seq 1 2$termCols |wc -l`
 
echo -e "#当终端的宽度最多能够正常打印$maxLineNum行\n#请输入要打印的三角形行数"
read -p "#行数范围大于1小于等于$maxLineNum,请输入行数:" lineNeeds
 
[[ `tput cols` -ne $termCols ]] && echo "终端宽度已经被改变,请重新运行脚本" &&exit 1
 
[[ $lineNeeds =~ ^[[:digit:]]+$ && $lineNeeds -ge 2 && $lineNeeds -le $maxLineNum ]]
 
[[ $? -ne 0 ]] && echo "输入值不合法" && exit
for line in `seq 1 $lineNeeds`;do
    #打印当前行的空格
    for((kong=(lineNeeds-line);kong>0;kong--));do
             echo -n " "
    done
    #打印当前行的星号
    for((xing=1;xing<=(line*2-1);xing++));do
             echo -n "*"
    done
    echo
done

 

 

2、用until循环实现国际象棋棋盘

#!/bin/bash
#
#
#
i=1
 
until [ $i -gt 8 ];do
    j=1
    while [ $j -gt 8 ];do
        sum=`expr $i + $j`
        z=`expr $sum % 2`
        [ $z -eq 0 ] && echo -ne "\033[41;1m  \033[0m"||echo -ne "\033[43;1m  \033[0m"
        let j++
    done
    echo
    let i++
done
 




以上是关于shell脚本进阶的主要内容,如果未能解决你的问题,请参考以下文章

SHELL脚本编程进阶

Shell脚本之进阶

代码片段:Shell脚本实现重复执行和多进程

shell脚本进阶

shell 脚本 片段

Linux shell脚本进阶使用