shell脚本进阶

1. bash条件判断

1.1 条件测试类型

  • 整数测试
  • 字符测试
  • 文件测试

1.2 条件测试的表达式

[ expression ]
[[ expression ]]
test expression

1.3 整数测试(双目)

-eq     //测试两个整数是否相等
[root@chenwanting ~]# [ 100 -eq 99 ] && echo yes || echo no
no

-ne     //测试两个整数是否不等
[root@chenwanting ~]# [ 100 -ne 99 ] && echo yes || echo no
yes

-gt     //测试一个数是否大于另一个数
[root@chenwanting ~]# [ 100 -gt 99 ] && echo yes || echo no
yes

-lt     //测试一个数是否小于另一个数
[root@chenwanting ~]# [ 100 -lt 99 ] && echo yes || echo no
no

-ge     //大于或等于
[root@chenwanting ~]# [ 100 -ge 99 ] && echo yes || echo no
yes

-le     //小于或等于
[root@chenwanting ~]# [ 100 -le 99 ] && echo yes || echo no
no

1.4 字符测试

==      //等值比较,检查==两边的内容是否一致,==两边都要有空格
[root@chenwanting ~]# [ t == t ] && echo yes || echo no
yes

!=      //检查两边内容是否不一致,不一致为真,一致为假
[root@chenwanting ~]# [ t != t ] && echo yes || echo no
no

=~      //左侧字符串是否能够被右侧的PATTERN所匹配到。此表达式应用于双中括号[[]]中
[root@chenwanting ~]# [[ tom =~ t ]] && echo yes || echo no
yes

-z "string"     //测试指定字符串是否为空,空则为真,不空则为假
[root@chenwanting ~]# [ -z "" ] && echo yes || echo no
yes
[root@chenwanting ~]# [ -z "ha" ] && echo yes || echo no
no

-n "string"     //测试指定字符串是否不空,不空则为真,空则为假
[root@chenwanting ~]# [ -n "t" ] && echo yes || echo no
yes
[root@chenwanting ~]# [ -n "" ] && echo yes || echo no
no

1.5 文件测试

//存在性测试:
    -e      //测试文件是否存在
    [root@chenwanting ~]# [ -e 123 ] && echo yes || echo no
yes

//存在性及类别测试:
    -b      //测试文件是否为块设备文件
    [root@chenwanting ~]# [ -b /dev/sr0 ] && echo yes || echo no
yes

    -c      //测试文件是否为字符设备文件
    [root@cwt ~]# [ -c /dev/tty5 ] && echo yes || echo no
yes

    -f      //测试文件是否为普通文件
    [root@chenwanting ~]# [ -f 1.sh ] && echo yes || echo no
yes

    -d      //测试指定路径是否为目录
 [root@chenwanting ~]# [ -d 100 ] && echo yes || echo no
yes

    -h      //测试文件是否为符号链接文件
    [root@cwt ~]# ln -s 1 2
[root@cwt ~]# ll
总用量 6828
-rw-r--r--.  1 root root      219 6月  26 09:39 1
-rw-r--r--.  1 root root      347 6月  25 11:35 1.sh
lrwxrwxrwx.  1 root root        1 6月  26 10:15 2 -> 1
-rw-------.  1 root root     1478 4月  12 10:43 anaconda-ks.cfg
-rw-r--r--.  1 root root      250 6月  26 09:49 chen.sh
drwxr-xr-x. 12  501 games    4096 6月  20 11:41 httpd-2.4.34
-rw-r--r--.  1 root root  6942969 6月  20 11:36 httpd-2.4.34.tar.bz2
-rw-r--r--.  1 root root      141 6月  25 11:53 jichu.sh
-rwxr-xr-x.  1 root root    18681 4月  13 09:47 Tetris.sh
[root@cwt ~]# [ -h 2 ] && echo yes || echo no
yes

    -L      //测试文件是否为符号链接文件
    [root@cwt ~]# [ -L 2 ] && echo yes || echo no
yes

    -p      //测试文件是否为命名管道文件
    -S      //测试文件是否为套接字文件
//文件权限测试:
    -r      //测试当前用户对指定文件是否有读权限
    -w      //测试当前用户对指定文件是否有写权限
    -x      //测试当前用户对指定文件是否有执行权限
//文件特殊权限测试:
    -g      //测试文件是否有sgid权限
    -u      //测试文件是否有suid权限
    -k      //测试文件是否有sticky权限
//文件大小测试:
    -s      //测试文件是否非空
//文件是否打开测试:
    -t fd   //fd表示的文件描述符是否已经打开且与某终端相关
//双目测试:
    file1 -ef file2     //测试file1与file2是否指向同一个设备上的相同inode,说白点就是两者是不是同一个文件
    file1 -nt file2     //测试file1是否比file2新
    file1 -ot file2     //测试file1是否比file2旧
//无分类:
    -N      //测试文件自从上一次被读取之后是否被修改过
    -O      //测试文件是否存在并且被当前用户拥有
    -G      //测试文件是否存在并且默认组是否为当前用户组

1.6 组合测试条件

-a      //与关系
[root@chenwanting ~]# [ 2 -gt 2 -a ! 3 -lt 5 ] && echo yes || echo no
no

-o      //或关系
[root@chenwanting ~]# [ 2 -gt 2 -o ! 3 -lt 5 ] && echo yes || echo no
no

!       //非关系

[ $# -gt 1 -a $# -le 3 ]
[ $# -gt 1 ] && [ $# -le 3 ]

1.7 条件判断,控制结构

1.7.1 单分支if语句

if 判断条件; then
    statement1
    statement2
    ......
fi
[root@chenwanting ~]# vim chen.sh
#!/bin/bash

read -p "请您输入一个数字:" sum
if [ $sum -gt 1 ];then

echo "你真棒!"

fi

1.7.2 双分支if语句

if 判断条件; then
    statement1
    statement2
    ......
else
    statement3
    statement4
    ......
fi
[root@chenwanting ~]# vim chen.sh
#!/bin/bash

read -p "请您输入一个数字:" sum
if [ $sum -gt 100 ];then

echo "你真棒!"
elif [ $sum -eq 88 ];then
        echo "caidui"
else
        echo "你错了!"
fi

1.7.3 多分支if语句

if 判断条件1; then
    statement1
    statement2
    ......
elif 判断条件2; then
    statement3
    statement4
    ......
else
    statement5
    statement6
    ......
fi
[root@chenwanting ~]# vim cwt.sh
#!/bin/bash

max_age=100

read -p "请您输入一个数字:" sum
if [ $sum -gt 0 -a $sum -lt 100 ];then

echo "你还能活多久 $[$max_age-$sum]岁!"
elif [ $sum -gt 100 ];then
echo "please try again(1-100)!"

fi

2. 分支选择

case $变量名 in            
value1)                
    statement                
    ...                
    ;;            
value2)                
    statement                
    ...                
    ;;            
*)                
    statement                
    ...                
    ;;        
esac

//case支持glob风格的通配符:
    *           //任意长度任意字符
    ?           //任意单个字符
    []          //指字范围内的任意单个字符
    abc|bcd     //abc或bcd

3. 循环语句

循环语句通常需要有一个进入条件和一个退出条件。

3.1 for循环

for循环当列表不为空时进入循环,否则退出循环

for 变量 in 列表; do
    循环体
done

for ((expr1;expr2;expr3))
{
    循环体
}

for (( expr1 ; expr2 ; expr3 ));do
    循环体
done

expr1   //用于指定初始条件,给控制变量一个初始值
expr2   //判定什么时候退出循环
expr3   //修正expr1指定的变量的值

//如何生成列表:
    {1..100}
    seq [起始数] [步进长度] 结束数
九九乘法表
[root@chenwanting ~]# vim e.sh
#!/bin/bash

for i in $(seq 9);do
for s in $(seq 9);do

        [ $s -le $i ]&& echo -n "[$i*$s]=$(($i*$s))"

done
 echo
done
[root@chenwanting ~]# bash e.sh 
[1*1]=1
[2*1]=2[2*2]=4
[3*1]=3[3*2]=6[3*3]=9
[4*1]=4[4*2]=8[4*3]=12[4*4]=16
[5*1]=5[5*2]=10[5*3]=15[5*4]=20[5*5]=25
[6*1]=6[6*2]=12[6*3]=18[6*4]=24[6*5]=30[6*6]=36
[7*1]=7[7*2]=14[7*3]=21[7*4]=28[7*5]=35[7*6]=42[7*7]=49
[8*1]=8[8*2]=16[8*3]=24[8*4]=32[8*5]=40[8*6]=48[8*7]=56[8*8]=64
[9*1]=9[9*2]=18[9*3]=27[9*4]=36[9*5]=45[9*6]=54[9*7]=63[9*8]=72[9*9]=81

3.2 while循环

while循环适用于循环次数未知的场景,注意要有退出条件。
条件满足时进入循环,条件不满足了退出循环。

3.2.1 while循环正常用法

while 条件; do
    statement
    ...
done

3.2.2 while循环特殊用法

//while循环特殊用法一:死循环
while :;do
    statement
    ...
done

//这里的冒号可以改成任何非空值

while循环特殊用法二:逐行读取某文件,将值存入line变量中
while read line;do
    statement
    ...
done < /path/to/somefile

3.3 until循环

条件不满足时进入循环,条件满足了退出循环。

until 条件; do
    statement
    ...
done

3.4 循环语句特殊情况

在循环语句中,有几种特别情况:

break [num]:提前退出循环。当循环语句中出现break时,将提前退出循环,不再执行循环后面的语句

continue [num]:提前结束本轮循环而进入下一轮循环。当循环语句执行到continue时,continue后面的语句将不再执行,提前进入下一轮循环

4. 定义脚本退出状态码

//exit命令用于定义执行状态结果

exit #      //此处的#号是一个数字,其范围可以是0-255

如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码

注意:脚本中一旦遇到exit命令,脚本会立即终止

你可能感兴趣的:(shell脚本进阶)