精华内容
参与话题
问答
  • for循环语句

    for循环语句

    在这里插入图片描述
    上一节讲了分支语句,本节介绍shell中的循环语句。shell中循环语句主要是三种:一种是for语句,另一种是while语句,最后一种是until-do语句

    利用for语句可以重复取出一个列表中的值,一次取一个,取完为止。建立脚本如下:

    #/bin/bash
    for item in Apple Boy Cake Dog Ege Fake;do
        echo $item
    done
    

    运行结果如下:

    Apple
    Boy
    Cake
    Dog
    Ege
    Fake
    

    注意:在C++中,如果我们写:

    for (int i = 0; i < 5 ;i++) {
            cout << i;
    }
    cout << i;
    

    会编译出错,因为第二个cout << i是访问不了i这个变量了,i的生命周期只存在于for循环里面。但是,shell脚本不一样,在for的外面仍然可以访问,比如上面这个脚本item在for结束后一直存着的都是Fake这个值。

    当列表中存在单引号的时候,两个单引号之间的内容会被当成一个整体,比如有一个脚本如下:

    #/bin/bash
    for item in Timmy hasn't ate Lucy's cake;do
        echo $item
    done
    

    运行结果如下:

    Timmy
    hasnt ate Lucys
    cake
    

    这个与预期的结果不一样,解决的方法有两个。第一个是在单引号前面增加转移符号\,第二种方法是使用双引号把包含单引号的整个单词框起来,当在一个单词的两边加上双引号时,双引号本身不会被当前单词的一部分。分别建立脚本如下:

    增加转义的脚本:

    #/bin/bash
    for item in Timmy hasn\'t ate Lucy\'s cake;do
        echo $item
    done
    

    使用双引号的脚本:

    #/bin/bash
    for item in Timmy "hasn't" ate "Lucy's" cake;do
        echo $item
    done
    

    两个脚本的运行结果相同,都为:

    Timmy
    hasn't
    ate
    Lucy's
    cake
    

    for默认根据空格来分割列表,所以如果列表中有不想被分割的空格,那么就用双引号包起来,举例如下:

    #/bin/bash
    for item in "Ji Gong" "Wu Lin Wai Zhuan";do
        echo $item
    done
    

    运行结果如下:

    Ji Gong
    Wu Lin Wai Zhuan
    

    在默认情况下,字符串以空格制表符换行符作为分隔符。比如说,我们现在从文件中用for去读取字符串,举例如下,首先建立一个文件testfile,内容为:

    wu lin wai zhuan
    di xia jiao tong zhan
    da ran fang
    

    然后建立脚本,这次从testfile文件中去读数据,脚本如下:

    #/bin/bash
    for item in $(cat testfile);do
        echo $item
    done
    

    运行后结果如下:

    wu
    lin
    wai
    zhuan
    di
    xia
    jiao
    tong
    zhan
    da
    ran
    fang
    

    这里把testfile中的换行空格都当作分割符了,有时候我们需要自己指定分隔符。这个时候我们只要改变环境变量IFS的值就可以了,IFS是内部字段分隔符,比如只以换行符对testfile进行分割,建立脚本如下:

    #/bin/bash
    IFS_old=$IFS
    IFS=$'\n'
    for item in $(cat testfile);do
        echo $item
    done
    IFS=$IFS_old
    

    运行结果如下:

    wu lin wai zhuan
    di xia jiao tong zhan
    da ran fang
    

    这里设置之前备份了一下IFS的值,用完之后又还原回来。

    for语句读取文件夹

    用for语句循环读取一个文件夹中的每个文件和文件夹,举例如下:

    #/bin/bash
    for item in /home/script/* /bin/*;do
        echo "$item"
    done
    

    运行如下:

    /home/script/1
    /home/script/test
    /home/script/test1.sh
    /bin/bash
    

    shell中类似C语言的for语句

    shell可以像C语言那样写for循环,举例如下:

    #/bin/bash
    for (( i = 1,j=3; i<=3 && j > 0; i++,j--));do
        echo "$i * $j = $[$i * $j]"
    done
    

    运行结果如下:

    1 * 3 = 3
    2 * 2 = 4
    3 * 1 = 3
    

    注意:这里的风格和C语言很像,只不过使用的是两个小括号。其中,变量取值不用加美元符号,并且赋初值的时候可以有空格,也可以不加空格,判断的时候也可以加空格或者不加空格。

    展开全文
  • Linux Shell 脚本中常用语句 1 for 语句 1.1 fordo…done (固定循环) for 这种语法,则是“已经知道要进行几次循环”的状态! for 的语法是: for var in con1 con2 con3 ... do 程序段 done 以上面的例子来...

    Linux Shell 脚本中常用语句

    1 for 语句

    1.1 for…do…done (固定循环)

    for 这种语法,则是“已经知道要进行几次循环”的状态!

    for 的语法

    for 的语法是:
    for var in con1 con2 con3 ...
    do
        程序段
    done
    以上面的例子来说,这个 $var 的变量内容在循环工作时:
    1. 第一次循环时, $var 的内容为 con1;
    2. 第二次循环时, $var 的内容为 con2;
    3. 第三次循环时, $var 的内容为 con3;
    4. ...

    示例如下:
    假设我有三种动物,分别是 dog, cat, elephant 三种,我想每一行都输出这样:“There are dogs”之类的字样,则可以编写脚本
    这里写图片描述
    执行如下:
    这里写图片描述

    1.2 for…do…done 的数值处理

    除了上述的方法之外 for 循环还有另外一种写法!

    for do done 数值处理

    语法如下:
    for (( 初始值; 限制值; 执行步阶 ))
    do
        程序段
    done
    
    这种语法适合于数值方式的运算当中,在 for 后面的括号内的三串内容意义为:
    1.初始值:某个变量在循环当中的起始值,直接以类似 i=1 设置好;
    2.限制值:当变量的值在这个限制值的范围内,就继续进行循环。例如 i<=100;
    3.执行步阶:每作一次循环时,变量的变化量。例如    i=i+1。
    注:在“执行步阶”的设置上,如果每次增加 1 ,则可以使用类似“i++”的方式,亦即
    是 i 每次循环都会增加一的意思

    示例如下:

    编辑 count.sh 脚本,内容如下
     10 #!/bin/bash
     11 read -p "Please input a number,I will count for 1+2+...+your_input:" nu
        # 交互式输入提示,键入数字,将从 1 一直加到你所键入的数字
     12 sum=0                    # 定义和值 sum = 0
     13 for (( i=1; i<=${nu}; i=i+1 ))    
        # 定义循环,变量 i = 1,i <= 你键入的数字,i 进行自加 
     14 do
     15         sum=$((${sum}+${i})) 
        # 每次循环都执行对 sum 的值加上 i 的值
     16 done
     17 echo "The result of '1+2+3+...+${nu}' is == ${sum}"
        # 输出求和结果

    编辑脚本进行连加
    这里写图片描述
    检测如下:输入 10
    这里写图片描述

    2 while 语句

    while do done(不定循环)

    while [ condition ]      # 中括号内的状态就是判断式
    do                       # 循环的开始!
        程序段落
    done                     # 循环的结束
    while 的中文是“当....时”所以,这种方式说的是“当 condition条件成立时,就进行循环,
    直到 condition 的条件不成立才停止”的意思

    示例如下:假设我要让使用者输入 yes 才结束程序的执行,否则就一直进行告知使用者输入字串

    编辑 test.sh 脚本,内容如下:
     10 #!/bin/bash
     11 while [ "${yn}" != "yes" -a "${yn}" != "YES" ]
        # 循环条件:输入不等于 yes 或着 YES 循环继续
     12 do
     13         read -p "Please input yes/YES to stop this program: " yn
     14 done
     15 echo "OK! you input the correct answer."

    执行如下:
    编辑脚本
    这里写图片描述
    测试如下
    这里写图片描述

    3 if 语句

    这个 if …. then 是最常见的条件判断式。简单的说,当符合某个条件判断的时候,就予以进行某项动作。if … then 的判断还有多层次的情况

    3.1单层、简单条件判断式

    如果只有一个判断式要进行,与” ||,&& “类似

     if [ 条件判断式 ];
     then
         执行操作  #当条件判断式成立时,可以进行的指令工作内容;
     fi      #将 if 反过来写,就成为 fi,结束 if 的意思!

    示例如下:
    利用 if 语句编写简单的脚本,实现,当脚本后输出为 cat 时,输出 dog
    编写如下:
    这里写图片描述
    执行如下:
    这里写图片描述

    3.2 多重、复杂条件判断式

    在同一个数据的判断中,如果该数据需要进行多种不同的判断时,就需要用到 if else 或者 if elif else 语句了

     一个条件判断,分成功进行与失败进行  (else)
     if [ 条件判断式 ]
     then
         当条件判断式成立时,可以进行的指令工作内容;
     else
         当条件判断式不成立时,可以进行的指令工作内容;
     fi
    
     多个条件判断 (if ... elif ... elif ... else) 分多种不同情况执行
     if [ 条件判断式一 ];
     then
         当条件判断式一成立时,可以进行的指令工作内容;
     elif [ 条件判断式二 ]; 
     then
         当条件判断式二成立时,可以进行的指令工作内容;
     else
         当条件判断式一与二均不成立时,可以进行的指令工作内容;
     fi

    elif 也是个判断式,因此出现 elif 后面都要接 then 来处理。但是 else 已经是最后的没有成立的结果了;所以 else 后面并没有 then
    示例如下:
    接上述脚本进行继续编写,当输入为 dog 时,输出 cat;当输入为 cat 时输出 dog 其他输出 提示输入 dog 或者 cat 。
    编写如下:
    这里写图片描述
    执行如下:
    这里写图片描述

    4 case ….. esac 语句

    if …. then …. fi ”对于变量的判断是以“比对”的方式来分辨的,如果符合状态就进行某些行为,并且通过较多层次(就是elif…)的方式来进行多个变量的程序码撰写。多层次的判断对于固定字符串的判定来说显得过于缓慢,若是我们所要求的判定在语句的最后,那就得等候多时才能得到想要的判定,这样显然不合理
    case…in….esac 语句只针对给定变量来设置状况,大大节省判定时间。

    语法如下:

     case $变量名称 in   # 关键字为 case ,还有变量前有钱字号
         "第一个变量内容") # 每个变量内容建议用双引 号括起来,关键字则为小括号 )
         程序段
         ;;      # 每个类别结尾使用两个连续的分号来处理!
         "第二个变量内容")
         程序段
         ;;
         *)             # 最后一个变量内容都会用 * 来代表所有其他值
                        # 不包含第一个变量内容与第二个变量内容的其他程序执行段
         exit   1
         ;;
     esac                   # 最终的 case 结尾。“反过来写”
    

    示例如下:
    编写脚本让使用者能够输入 A,B,C,并且将使用者的变量显示到屏幕上,如果不是 A,B,C时就告知使用者仅有这三种选择。只有选择正确才会退出。
    编写如下:
    这里写图片描述
    执行如下:
    这里写图片描述

    展开全文
  • 一、三脚本退语句 Exit 结束脚本,整体退出 Break 允许跳出所有循环(终止执行后面的所有循环) Continue 提前结束当前循环,进入下一循环 为了更清楚的了解这几的区别进行以下实验: root@...

    一、三个脚本退出语句

    Exit 结束脚本,整体退出
    Break 允许跳出所有循环(终止执行后面的所有循环)
    Continue 提前结束当前循环,进入下一个循环

    为了更清楚的了解这几个的区别进行以下实验:
    root@desktop26 mnt]# cat test1.sh 
    #######################################
    # Author:       yifan                 #
    # Version:                            #
    # Mail:                               #
    # Date:         2018-51-06/25/18      #
    # Description:                        #
    #                                     #
    #######################################
    
    #!/bin/bash
    for NUM in {1..5}          //从1到4循环
    do
            if 
            [ "$NUM " -eq  3 ]  //判断NUM是否等于3
        then  
              $1      //这里输入脚本后输入的三个测试值
        fi
        echo $NUM      
    done
    echo hello
    [root@desktop26 mnt]# sh  test1.sh exit    //当NUM=3后直接全部退出脚本
    1
    2
    [root@desktop26 mnt]# sh test1.sh continue  //当NUM=3后,不执行后面的“echo NUM”,直接进入下次循环
    1
    2
    4
    5
    hello
    [root@desktop26 mnt]# sh  test1.sh break  //结束for的所有循环,进入下一步命令“echo hello”
    1
    2
    hello

    这里写图片描述
    这里写图片描述

    二、for语句

    for做的是批处理
    格式:
    for (变量)in (取值)
    do
    done

    2.1 、{1..5}和`seq 1 5`的辨析

       {1..5}是1到5循环,`seq 1 5 `也是1到5循环,但不同的时seq可以设定步长 ,比如` seq 1 2 6`指的是从1到6每次增加两个数,而且seq 比”{}”更高级,其里面可以加变量名。但是“{}”内不可识别变量。

    为了更清楚的比较,我们来看以下实验:
    [root@desktop26 mnt]# cat test2.sh 
    #!/bin/bash
    for NUM in {1..5}     //{1..5}
    do
            echo $NUM  
    done
    [root@desktop26 mnt]# sh  test2.sh 
    1
    2
    3
    4
    5
    [root@desktop26 mnt]# vim test2.sh
    [root@desktop26 mnt]# cat test2.sh 
    #!/bin/bash
    for NUM in `seq 1 5`
    do
            echo $NUM  
    done
    [root@desktop26 mnt]# sh  test2.sh 
    1
    2
    3
    4
    5
    [root@desktop26 mnt]# vim test2.sh
    [root@desktop26 mnt]# cat test2.sh 
    #!/bin/bash
    for NUM in `seq 1 2 5`  //从1到5,步长为2,即1.3.5.
    do
            echo $NUM  
    done
    [root@desktop26 mnt]# sh  test2.sh 
    1
    3
    5
    

    这里写图片描述
    这里写图片描述

    实验一:判断机房IP是否ping通

    #!/bin/bash
    for HOSTNUMBER in `seq 1 50`
    do
       ping -c1 -w1 172.25.254.$HOSTNUMBER &>/dev/null && {    
              echo -e "\033[32m 172.25.254.$HOSTNUMBER is up;\033[0m"     
    } || {
              echo -e "\033[31m 172.25.254.$HOSTNUMBER is down;\033[0m"
    }        //ping通显示ip up ,否则显示 ip down,/033加的是输出的颜色值,此时需加-e识别。
    done
    
    [root@desktop mnt]# sh  check_host.sh 
     172.25.254.1 is up;
     172.25.254.2 is up;
     172.25.254.3 is up;
     172.25.254.4 is up;
     172.25.254.5 is up;
     172.25.254.6 is up;
     172.25.254.7 is up;
     172.25.254.8 is up;
     172.25.254.9 is up;
     172.25.254.10 is up;
     172.25.254.11 is up;
     172.25.254.12 is down;
     172.25.254.13 is up;
     172.25.254.14 is up;
     172.25.254.15 is down;
     172.25.254.16 is up;
     172.25.254.17 is up;
     172.25.254.18 is down;
     172.25.254.19 is up;
     172.25.254.20 is up;
     172.25.254.21 is up;
     172.25.254.22 is down;
     172.25.254.23 is up;
     172.25.254.24 is down;
     172.25.254.25 is up;
     172.25.254.26 is up;
     172.25.254.27 is up;
     172.25.254.28 is up;
     172.25.254.29 is up;
     172.25.254.30 is up;
     172.25.254.31 is down;
     172.25.254.32 is up;
     172.25.254.33 is up;
     172.25.254.34 is down;
     172.25.254.35 is up;
     172.25.254.36 is up;
     172.25.254.37 is up;
     172.25.254.38 is up;
     172.25.254.39 is up;
     172.25.254.40 is up;
     172.25.254.41 is up;
     172.25.254.42 is up;
     172.25.254.43 is up;
     172.25.254.44 is up;
     172.25.254.45 is up;
     172.25.254.46 is up;
     172.25.254.47 is up;
     172.25.254.48 is up;
     172.25.254.49 is up;
     172.25.254.50 is down;
    

    这里写图片描述
    这里写图片描述

    实验二:建立一个数据库,利用脚本对所有数据库进行备份操作,每个数据库备份到一个文件中,并以.sql结尾,最后存储在到/mnt/mysql_dump目录下。

    1.建立数据库:
    
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MariaDB connection id is 2
    Server version: 5.5.35-MariaDB MariaDB Server
    
    Copyright (c) 2000, 2013, Oracle, Monty Program Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MariaDB [(none)]> create database linux;
    Query OK, 1 row affected (0.10 sec)
    
    MariaDB [(none)]> use linux
    Database changed
    MariaDB [linux]> create table linux_user(
        -> username varchar(50) not null,
        -> password varchar(50) not null);
    Query OK, 0 rows affected (0.14 sec)
    
    MariaDB [linux]> insert into linux_user values("user1","123");
    Query OK, 1 row affected (0.11 sec)
    
    MariaDB [linux]> insert into linux_user values("user2","234");
    Query OK, 1 row affected (0.10 sec)
    
    MariaDB [linux]> select * from linux_user;
    +----------+----------+
    | username | password |
    +----------+----------+
    | user1    | 123      |
    | user2    | 234      |
    +----------+----------+2 rows in set (0.00 sec)
    
    MariaDB [linux]> quit
    Bye

    这里写图片描述

    2.编写脚本如下:

    这里写图片描述

    三、while语句

    格式(当条件为真时执行do):
    while true
    do
    done

    实验一:编写脚本,实时监控根分区的使用情况,超过80%就给超级用户发送一封警告邮件

    脚本内容:
    [root@localhost mnt]# vim warning.sh
    #!/bin/bash
    NUM=`df -h | awk '/\/$/{print $5}' | awk -F "%" '{print $1}'`   //筛选出/使用情况百分比数字
    while true
    do
            [ "$NUM" -ge 80 ] && {
                    echo "Your / will full !" | mail -s warning root
            }
            sleep 1    //每隔1秒执行一次
    done                                                   

    这里写图片描述

    root@node1 mnt]# df  //查看根分区使用情况
    Filesystem           Used Available Use% Mounted on
    /dev/vda1           10473900 9488536    985364  29% /
    devtmpfs              469344       0    469344   0% /dev
    tmpfs                 484932      84    484848   1% /dev/shm
    tmpfs                 484932   12784    472148   3% /run
    tmpfs                 484932       0    484932   0% /sys/fs/cgroup
    /dev/mapper/vg0-vo    483670    2368    451811   1% /home
    [root@node1 mnt]# sh test.sh &  //执行脚本,并打入后台
    [3] 4151
    [root@node1 mnt]# mail  //查看没有邮件
    No mail for root
    [root@node1 mnt]# dd if=/dev/zero of=/bigfile bs=1M count=6000//截取6000M的内存使根分区使用率变成80%以上
    [root@node1 mnt]# df
    Filesystem             Used Available Use% Mounted on
    /dev/vda1           10473900 9488536    985364  91% /
    devtmpfs              469344       0    469344   0% /dev
    tmpfs                 484932      84    484848   1% /dev/shm
    tmpfs                 484932   12784    472148   3% /run
    tmpfs                 484932       0    484932   0% /sys/fs/cgroup
    /dev/mapper/vg0-vo    483670    2368    451811   1% /home
    [root@node1 mnt]# sh test.sh &  //执行脚本并打入后台
    [3] 4151
    [root@node1 mnt]# mail  //可以查到邮件
    Heirloom Mail version 12.5 7/5/10.  Type ? for help."/var/spool/mail/root": 23 messages 23 new
    >N  1 root                  Thu Jun 27 03:11  18/590   "warning"
     N  2 root                  Thu Jun 27 03:11  18/590   "warning"
     N  3 root                  Thu Jun 27 03:11  18/590   "warning"
     N  4 root                  Thu Jun 27 03:11  18/590   "warning"

    四、If语句

    格式
    if
    then
    elif
    then
    、、、、、
    else
    fi

    实验一:编写脚本,判断文件类型

    脚本内容:
    #!/bin/bash
    if
    [ "$#" -ne "1" ]
    then
        echo " please input a file  after script!!"
    
    elif
    [ ! -e "$1" ]
    then
        echo " $1 is not exist! "
    elif
    [ -b "$1" ]
    then
    
        echo " $1 is a block special!"
    elif
    [ -f "$1" ]
    then
    
        echo " $1 is a regular file!"
    elif
    [ -L "$1" ]
    then
    
        echo " $1 is a symbolic link! "
    elif
    [ -d "$1" ]
    then
    
        echo " $1 is a directory! "
    else
       echo unknow $1
    fi

    这里写图片描述

    测试:
    [root@localhost mnt]# sh check_file.sh mysql_dump
     mysql_dump is a directory! 
    [root@localhost mnt]# sh check_file.sh check_file.sh 
     check_file.sh is a regular file!
    [root@localhost mnt]# sh check_file.sh
     please input a file  after script!!
    

    实验二:写一个创建用户的脚本,后更用户文件和密码文件且符合下列要求

    1.文件数量不对报错;

    2.文件不存在报错;

    3.两个文件存在差异报错;4.用户存在时显示用户存在。但是不改变此用户的密码。

    5.用户不存在时,建立用户并设定相应的密码

    脚本内容:
    [root@localhost mnt]# cat user_create.sh
    #!/bin/bash
    ##############################Check Rule########################################
    if
    [ "$#" -ne "2" ]//判断输入文件是否为两个
    then
    
        echo  -e "\033[31m please give me userfile and passfile after script !!\033[0m"   
        exit 1
    
    elif
    [ ! -e "$1" ]  //判断输入文件1是否为存在
    then
        echo -e  "\033[31m $1 is not exist ! \033[0m "
        exit 1
    elif
    [ ! -e "$2" ] //判断输入文件2是否为存在
    then
        echo -e  "\033[31m $2 is not exist ! \033[0m "
        exit 1
    elif {
     N1=`awk 'BEGIN{N=0}{N++}END{print N}' $1`   //判断输入文件1、2行数是否对应相等
     N2=`awk 'BEGIN{N=0}{N++}END{print N}' $2`  
    [ "$N1" -ne " $N2" ]
    }
    then
    
        echo -e "\033[31m $1's lines is not equal to $2's lines ! \033[0m "
        exit 1
    fi
    #############################Create User#####################################
    for LINES in `seq 1 $N1`
    do
    
            USERNAME=`sed -n "${LINES}p" $1`
            PASSWORD=`sed -n "${LINES}p" $2`
            useradd $USERNAME
            [ "$?" -eq "0" ]      //建立用户返回值为真则建立成功,否则不建立
            echo $PASSWORD | passwd --stadin $USERNAME &> /dev/null && echo $USERNAME created !
    done

    这里写图片描述

    测试:
    [root@localhost mnt]# cat userfile 
    user1
    user2
    user3
    [root@localhost mnt]# cat passfile 
    123
    456
    [root@localhost mnt]# sh user_create.sh userfile passfile   //行数不相同
     userfile's lines is not equal to passfile's lines !  
    [root@localhost mnt]# sh user_create.sh userfile 
     please give me userfile and passfile after script !!    //为加文件
    [root@localhost mnt]# vim passfile 
    [root@localhost mnt]# cat passfile   //行数相同
    123
    789
    456
    [root@localhost mnt]# sh user_create.sh userfile passfile  
    [root@localhost mnt]# id user1
    uid=1001(user1) gid=1001(user1) groups=1001(user1)
    [root@localhost mnt]# id user2
    uid=1002(user2) gid=1002(user2) groups=1002(user2)
    [root@localhost mnt]# id user3
    uid=1003(user3) gid=1003(user3) groups=1003(user3)    //建立成功
    [root@localhost mnt]# vim user_create.sh
    [root@localhost mnt]# sh user_create.sh userfile passfile  //用户已存在,不建立
    useradd: user 'user1' already exists
    useradd: user 'user2' already exists
    useradd: user 'user3' already exists

    这里写图片描述

    五、case语句

    格式:
    case $1 in
    dog) //第一种情况
    echo cat
    ;;
    cat) //第二种情况
    echo dog
    ;;
    *) //第三种情况
    echo error
    esac

    实验一:测试if和case执行次数。

    [root@localhost mnt]# cat test.sh    //for语句
    #!/bin/bash
    if
    [ "$1" = "dog" ]  
    then
    
       echo "cat!"
    elif
    [ "$1" = "cat" ]
    then
    
      echo "dog!"
    else
    
      echo "ERROR: please input "cat" or "dog" follow script !"
    fi
    
    [root@localhost mnt]# sh -x test.sh cat   //执行两次
    + '[' cat = dog ']'
    + '[' cat = cat ']'
    + echo 'dog!'
    dog!
    [root@localhost mnt]# sh -x test.sh dog  //执行一次
    + '[' dog = dog ']'
    + echo 'cat!'
    cat!
    [root@localhost mnt]# cat text1.sh   //case语句
    #!/bin/bash
    case $1 in
            dog)
            echo cat
        ;;
        cat)
        echo dog
        ;;
        *)
        echo error
    esac
    [root@localhost mnt]# sh -x  text1.sh dog  //执行一次
    + case $1 in
    + echo cat
    cat
    [root@localhost mnt]# sh -x  text1.sh cat  //执行一次
    + case $1 in
    + echo dog
    dog
    

    这里写图片描述
    这里写图片描述
    这里写图片描述

    展开全文
  • 技术大佬:我去,你写的 switch 语句也太老土了吧

    万次阅读 多人点赞 2020-03-01 09:02:53
    但当我看到他们当中有一人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!” 来看看小王写的代码吧,看完不要骂我装逼啊。 private static String createPlayer...

    昨天早上通过远程的方式 review 了两名新来同事的代码,大部分代码都写得很漂亮,严谨的同时注释也很到位,这令我非常满意。但当我看到他们当中有一个人写的 switch 语句时,还是忍不住破口大骂:“我擦,小王,你丫写的 switch 语句也太老土了吧!”

    来看看小王写的代码吧,看完不要骂我装逼啊。

    private static String createPlayer(PlayerTypes playerType) {
        switch (playerType) {
            case TENNIS:
                return "网球运动员费德勒";
            case FOOTBALL:
                return "足球运动员C罗";
            case BASKETBALL:
                return "篮球运动员詹姆斯";
            case UNKNOWN:
                throw new IllegalArgumentException("未知");
            default:
                throw new IllegalArgumentException(
                        "运动员类型: " + playerType);
    
        }
    }
    

    看完上述代码后,你是不是会发出这样的感慨——“代码写得很好,没有任何问题啊!”是不是觉得我在无事生非,错怪了小王!但此时我要送上《了不起的盖茨比》中的一句话:

    我年纪还轻,阅历不深的时候,我父亲教导过我一句话,我至今还念念不忘。 “每逢你想要批评任何人的时候, ”他对我说,“你就记住,这个世界上所有的人,并不是个个都有过你拥有的那些优越条件。”

    哈哈,这句话不光是让你看的,也是给我看的。是时候冷静下来谈谈上述 switch 语句的老土问题了。

    看到上图了吧,当不小心删掉 default 语句后,编译器就会报错,提示:“没有返回语句”,为了解决这个问题,我们可以新建一个 player 变量作为返回结果,就像下面这样:

    private static String createPlayer(PlayerTypes playerType) {
        String player = null;
        switch (playerType) {
            case TENNIS:
                player = "网球运动员费德勒";
                break;
            case FOOTBALL:
                player = "足球运动员C罗";
                break;
            case BASKETBALL:
                player = "篮球运动员詹姆斯";
                break;
            case UNKNOWN:
                throw new IllegalArgumentException("未知");
        }
    
        return player;
    }
    

    当添加了 player 变量后,case 语句中就需要添加上 break 关键字;另外在 switch 语句结束后,返回 player。这时候,编译器并不会提示任何错误,说明 default 语句在这种情况下是可以省略的。

    从 JDK 12 开始(本例使用的是 JDK 13),switch 语句升级了,不仅可以像传统的 switch 语句那样作为条件的判断,还可以直接作为一个返回结果。来对小王的代码进行改造,如下所示:

    private static String createPlayer(PlayerTypes playerType) {
       return switch (playerType) {
            case TENNIS -> "网球运动员费德勒";
            case FOOTBALL -> "足球运动员C罗";
            case BASKETBALL -> "篮球运动员詹姆斯";
            case UNKNOWN ->  throw new IllegalArgumentException("未知");
        };
    }
    

    够 fashion 吧?不仅 switch 关键字之前加了 return 关键字,case 中还见到了 Lambda 表达式的影子,中划线和箭头替代了冒号,意味着箭头右侧的代码只管执行无须 break。

    并且,default 语句变成了可选项,可有可无,不信?你也动手试试。

    新的 switch 语句足够的智能化,除了有上述的 3 个优势,还可以对枚举类型的条件进行校验。假如在 PlayerTypes 中增加了新的类型 PINGPANG(乒乓球):

    public enum PlayerTypes {
        TENNIS,
        FOOTBALL,
        BASKETBALL,
        PINGPANG,
        UNKNOWN
    }
    

    此时编译器会发出以下警告:

    意思就是 switch 中的 case 条件没有完全覆盖枚举中可能存在的值。好吧,那就把 PINGPANG 的条件加上吧。来看一下完整的代码:

    public class OldSwitchDemo {
        public enum PlayerTypes {
            TENNIS,
            FOOTBALL,
            BASKETBALL,
            PINGPANG,
            UNKNOWN
        }
    
        public static void main(String[] args) {
            System.out.println(createPlayer(PlayerTypes.BASKETBALL));
        }
    
        private static String createPlayer(PlayerTypes playerType) {
            return switch (playerType) {
                case TENNIS -> "网球运动员费德勒";
                case FOOTBALL -> "足球运动员C罗";
                case BASKETBALL -> "篮球运动员詹姆斯";
                case PINGPANG -> "乒乓球运动员马龙";
                case UNKNOWN -> throw new IllegalArgumentException("未知");
            };
        }
    }
    

    switch 语句变成了强大的 switch 表达式,美滋滋啊!那假如一个运动员既会打篮球又会打乒乓球呢?

    private static String createPlayer(PlayerTypes playerType) {
        return switch (playerType) {
            case TENNIS -> "网球运动员费德勒";
            case FOOTBALL -> "足球运动员C罗";
            case BASKETBALL,PINGPANG -> "牛逼运动员沉默王二";
            case UNKNOWN -> throw new IllegalArgumentException("未知");
        };
    }
    

    就像上述代码那样,使用英文逗号“,”把条件分割开就行了,666 啊!

    不服气?switch 表达式还有更厉害的,-> 右侧还可以是 {} 括起来的代码块,就像 Lambda 表达式那样。

    private static String createPlayer(PlayerTypes playerType) {
        return switch (playerType) {
            case TENNIS -> {
                System.out.println("网球");
                yield "网球运动员费德勒";
            }
            case FOOTBALL -> {
                System.out.println("足球");
                yield "足球运动员C罗";
            }
            case BASKETBALL -> {
                System.out.println("篮球");
                yield "篮球运动员詹姆斯";
            }
            case PINGPANG -> {
                System.out.println("乒乓球");
                yield "乒乓球运动员马龙";
            }
            case UNKNOWN -> throw new IllegalArgumentException("未知");
        };
    }
    

    细心的同学会发现一个之前素未谋面的关键字 yield,它和传统的 return、break 有什么区别呢?

    先来看官方的解释:

    A yield statement transfers control by causing an enclosing switch expression to produce a specified value.

    意思就是说 yield 语句通过使一个封闭的 switch 表达式产生一个指定值来转移控制权。为了进一步地了解 yield 关键字,我们可以反编译一下字节码:

    private static String createPlayer(NewSwitchDemo3.PlayerTypes playerType) {
        String var10000;
        switch(playerType) {
            case TENNIS:
                System.out.println("网球");
                var10000 = "网球运动员费德勒";
                break;
            case FOOTBALL:
                System.out.println("足球");
                var10000 = "足球运动员C罗";
                break;
            case BASKETBALL:
                System.out.println("篮球");
                var10000 = "篮球运动员詹姆斯";
                break;
            case PINGPANG:
                System.out.println("乒乓球");
                var10000 = "乒乓球运动员马龙";
                break;
            case UNKNOWN:
                throw new IllegalArgumentException("未知");
            default:
                throw new IncompatibleClassChangeError();
        }
    
        return var10000;
    }
    

    编译器在生成字节码的时候对 yield 关键字做了自动化转义,转成了传统的 break 语句。这下清楚了吧?

    但是,话又说出来,那些看似 fashion 的代码也不过是把部分秀技的工作交给了编译器,还可能存在对旧版本不兼容、对队友不友好的问题——代码土点就土点呗,没准是最实用的。

    “不好意思,我为昨天早上的嚣张向你道歉。。。。。。”我向小王发送了一条信息。

    好了,我亲爱的读者朋友,以上就是本文的全部内容了,希望能够博得你的欢心。

    最后,一定会有不少读者想要问我怎么学习 Java 的,那我干脆就把我看过的优质书籍贡献出来:

    1)入门版:《Head First Java》、《Java 核心技术卷》

    2)进阶版:《Java编程思想》、《Effective Java》、《Java网络编程》、《代码整洁之道》

    3)大牛版:《Java并发编程》、《深入理解Java虚拟机》、《Java性能权威指南》、《重构》、《算法》

    就先介绍这么多,希望对那些不知道看什么书的同学有所帮助。

    对了,我介绍的这些书籍,已经顺便帮你整理好了,你可以在我的原创微信公众号『沉默王二』回复『书籍』获取哦

    有收获?希望老铁们来个三连击,给更多的同学看到这篇文章

    展开全文
  • switch语句

    万次阅读 多人点赞 2019-02-17 19:36:16
    switch语句从字面上讲,可以称为开关语句,当然理解上不要以为就只有开和关,可以想象它是一多路开关。它是一种多分支结构。 switch语句的语法形式为: switch(整型表达式) { case 常量表达式1:语句1 case ...
  • Switch语句

    千次阅读 2016-10-07 12:39:07
    switch作为选择语句,实际编程中,最易...1、switch语句称为情况选择语句,又称开关语句。JDK1.7之前的switch语句限定对整形数据进行判断。 switch(表达式){  case 常量值1:  代码块1;  break;  case 常量值2:
  • switch 语句

    千次阅读 2017-07-28 09:42:24
    switch 语句 switch 的优势:1.选择结构更加清晰,一目了然  2.执行速度相对较快 switch的执行逻辑:从switch后边圆括号里的变量与从case后边的常量开始的地方开始,依次执行后边的指令,直到指令结束。 case的...
  • if语句和switch语句的选择与区别

    千次阅读 多人点赞 2019-01-13 15:40:44
    if语句和Switch语句的选择 if选择结构 基本if选择结构: 处理单一或组合条件的情况 if-else选择结构:处理简单的条件分支情况 多重if选择结构:处理复杂的条件分支情况 嵌套if选择结构:用于较为复杂的流程控制 ...
  • if switch for if / switch判断语句 ==&gt;流程控制: 决定逻辑运行的走向 , 根据条件决定如何做出反应 语法: 判断条件为真,则走进{ } 中 执行语句 if(判断条件){ //执行语句 } 判断条件会自动转为布尔值...
  • switch语句是一种多分支选择结构。 switch 分支选择语句就像一人手上拿着一号码,只有出现能另外一匹配的号码才能进行下一步操作,注意与 if 语句区分开,if 是判断真假,只存在真和假种状态,而switch ...
  • C语言switch语句的用法详解

    万次阅读 多人点赞 2019-08-14 16:19:33
    C语言提供了一种用于多分支选择的switch语句, 其一般形式为: switch(表达式){ case 常量表达式1: 语句1; case 常量表达式2: 语句2; … case 常量表达式n: 语句n; default: 语句n+1; } 其语义是:计算...
  • Java switch语句

    万次阅读 2019-06-27 08:19:48
    switch case 语句有如下规则: switch 语句中的变量类型可以是: byte、short、int 或者 ...switch 语句可以拥有多 case 语句。每 case 后面跟一要比较的值和冒号。 case 语句中的值的数据类型必须与变量的...
  • C++ switch语句详解

    万次阅读 多人点赞 2017-02-07 12:28:35
    switch语句的功能是:根据给定条件从多分支语句序列中选择一作为执行入口。 基本格式 switch语句的基本格式如下:  switch (表达式) {  case 常量表达式1:《语句序列1》《break;》 //《》中的内容可省 ...
  • switch语句及三种循环语句

    千次阅读 2019-07-31 18:21:21
    switch语句 语句格式 switch(表达式){ case 1: 语句1; break; case 2: 语句2; break; .... default: 语句体n+1; break; } 执行流程 首先计算出表达式的值 其次,和case依次比较,...
  • C# switch 语句

    千次阅读 2019-06-21 10:59:01
    查看更多 https://www.yuque.com/docs/share/b9547cf7-3b83-43c7-ad4f-70850b57ce07
  • switch语句用法实例

    万次阅读 多人点赞 2018-10-15 17:28:22
    学生成绩等级 #include&amp;lt;stdio.h&...switch(grade) { case 10:printf(“等级为A\n”);break; case 9:printf(“等级为A\n”);break; case 8:printf(“等级为B\n”);break; case 7:printf...
  • Python中如何优雅地使用switch语句

    万次阅读 2019-03-08 03:29:06
    文章目录Python中如何优雅地使用switch语句案例一(简单情况)案例二(带条件判断) 版权声明:本文为博主原创文章,转载请注明原文出处! 写作时间:2019-03-07 13:49:45 Python中如何优雅地使用switch语句 我们...
  • 1:switch语句 格式 //注意事项switch格式的break只会结束switch语句,不会影响方法里其他程序 switch(表达式){ case值1: 语句体; break; case值2: 语句体2; break; default: 语句体n+1; [break;] }...
  • C语言 switch语句举例说明(类比坐电梯来理解)

    万次阅读 多人点赞 2018-12-19 12:07:21
    我们把**使用switch语句的过程规律**想象成坐**电梯**(大家都有坐电梯的经历),每**case语句**后面的标号相当于一**按钮**,你要在哪一层下去,就按那一层按钮,就可以在这一层下去。
  • C语言switch语句用法详解

    万次阅读 多人点赞 2018-06-18 17:42:02
    switch语句的一般形式: switch(整形表达式) {   case 常量表达式1: 语句1;  case 常量表达式2: 语句2;  …   case 常量表达式n: 语句n;  default: 语句n+1; } switch主要需要注意的方面有两个: 1、...
  • 1、 输入一组整数a,输出其中奇偶数、奇偶数的和、积以及数。 clear clc n=input('输入数字数'); for i=1:n x(i)=input('输入数字:'); end j=1;k=1; %y向量存奇数,z向量存偶数 for i=1:n if mod(x(i),2) y...
  • C++中的switch语句

    千次阅读 2019-02-16 12:08:03
    C++中的switch语句
  • switch语句的用法详解

    万次阅读 多人点赞 2015-10-27 13:54:33
    switch语句的用法详解C语言还提供了另一种用于多分支选择的switch语句, 其一般形式为:switch(表达式) { case常量表达式1: 语句1; case常量表达式2: 语句2; … case常量表达式n: 语句n; default:语句n+1; }...
  • switch语句的用法实例

    2019-07-25 15:52:00
    switch 语句允许测试一变量等于多值时的情况。每值称为一 case,且被测试的变量会对每 switch case 进行检查。 switch 语句必须遵循下面的规则: 1.在一 switch 中可以有任意数量的 case 语句。...
  • if语句和switch语句的区别

    千次阅读 2017-05-17 15:40:15
    if语句案例 import java.util.Scanner; public class Switch1{ public static void main(String[] args){ System.out.println("请输入(1-4)的数字"); Scanner sc = new Scanner(System.in); int num = sc....
  • java switch语句

    千次阅读 2018-07-25 02:06:00
    先看一下java switch的基本类型:  Scanner ss=new Scanner(System.in); // 这里是输入的前提 只要是需要我们输入东西这就是前提  int sz = ss.nextInt(); ...

空空如也

1 2 3 4 5 ... 20
收藏数 283,017
精华内容 113,206
关键字:

do两个语句 for shell