shell进阶

1. 条件判断

1.1 条件判断类型

  • 整数测试 // 判断大小,是否相等
  • 字符测试 // 判断字符串的字母顺序等
  • 文件测试 // 是否存在,大小等

1.2 条件测试表达式

[ expression ]
[[ expression ]]
test expression
[root@master ~]# [ 1 -gt 2 ] ## 前后要有空格
[root@master ~]# echo $?
1
[root@master ~]# [[ 1 -gt 2 ]]
[root@master ~]# echo $?
1
[root@master ~]# test 1 -gt 2
[root@master ~]# echo $?
1
# 判断1是否大于2

1.3 整数测试(双目(2个数测试为双目))

-eq     //测试两个整数是否相等
-ne     //测试两个整数是否不等
-gt     //测试一个数是否大于另一个数
-lt     //测试一个数是否小于另一个数
-ge     //大于或等于
-le     //小于或等于
#均为英文单词缩写

1.4 字符测试

==      //等值比较,检查==两边的内容是否一致,==两边都要有空格
!=      //检查两边内容是否不一致,不一致为真,一致为假
=~      //左侧字符串是否能够被右侧的PATTERN所匹配到。此表达式应用于双中括号[[]]中
-z "string"     //测试指定字符串是否为空,空则为真,不空则为假
-n "string"     //测试指定字符串是否不空,不空则为真,空则为假
[root@master ~]# [ 'abc1' == 'abc' ]
[root@master ~]# echo $?
1
[root@master ~]# [[ 'abc1' =~ a. ]]
[root@master ~]# echo $?
0
[root@master ~]# [[ 'abc1' =~ 'a.' ]]
[root@master ~]# echo $?
1
[root@master ~]# [[ 'abc1' =~ "a." ]]
[root@master ~]# echo $?
1
[root@master ~]# [ -z "" ]
[root@master ~]# echo $?
0
[root@master ~]# [ -z " " ]
[root@master ~]# echo $?
1
[root@master ~]# a=
[root@master ~]# [ -z $a]
[root@master ~]# echo $?
0
[root@master ~]# a=10
[root@master ~]# [ -z $a ]
[root@master ~]# echo $?
1
[root@master ~]# [[ 'azc' > 'adb' ]]
[root@master ~]# echo $?
0
[root@master ~]# [[ 'azc' > 'acz' ]]
[root@master ~]# echo $?
0
[root@master ~]# [[ 'azc' < 'acz' ]]
[root@master ~]# echo $?
1
[root@master ~]# [[ 'Azc' > 'bzc' ]]
[root@master ~]# echo $?
1
[root@master ~]# [[ 'Azc' > 'azc' ]]
[root@master ~]# echo $?
0
#字母相同时,大写的字母大
#大致按ASCII表来看, 

1.5 文件测试

//存在性测试:
    -e      //测试文件是否存在
//存在性及类别测试:
    -b      //测试文件是否为块设备文件
    -c      //测试文件是否为字符设备文件
    -f      //测试文件是否为普通文件
    -d      //测试指定路径是否为目录
    -h      //测试文件是否为符号链接文件
    -L      //测试文件是否为符号链接文件
    -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      //测试文件是否存在并且默认组是否为当前用户组
[root@master ~]# touch abc
[root@master ~]# [ -e abc ]
[root@master ~]# echo $?
0
[root@master ~]# mkdir ab
[root@master ~]# [ -e ab ]
[root@master ~]# echo $?
0
[root@master ~]# [ -f abc ]
[root@master ~]# echo $?
0
[root@master ~]# [ -f ab ]
[root@master ~]# echo $?
1

1.6 组合测试条件

-a      //与关系
-o      //或关系
!       //非关系
[root@master ~]# [ 1 -gt 2 -a 2 -gt 1 ]
[root@master ~]# echo $?
1
[root@master ~]# [ 1 -lt 2 -a 2 -gt 1 ]
[root@master ~]# echo $?
0
[root@master ~]# [ 1 -gt 2 -o 2 -gt 1 ]
[root@master ~]# echo $?
0
[root@master ~]# [ 1 -lt 2 ] && [ 2 -gt 1 ]
[root@master ~]# echo $?
0

1.7 条件判断,控制结构

1.7.1 单分支if语句

if 判断条件; then
    statement1
    statement2
    ......
fi
[root@master ~]# bash useradd.sh tom
[root@master ~]# id tom
uid=1001(tom) gid=1001(tom)=1001(tom)
[root@master ~]# bash useradd.sh tom
[root@master ~]# cat useradd.sh 
#!/bin/bash

id $1 &> /dev/null #不显示输出

if [ $? -ne 0 ];then 
  useradd $1
fi

1.7.2 双分支if语句

if 判断条件; then
    statement1
    statement2
    ......
else
    statement3
    statement4
    ......
fi

1.7.3 多分支if语句

if 判断条件1; then
    statement1
    statement2
    ......
elif 判断条件2; then
    statement3
    statement4
    ......
else
    statement5
    statement6
    ......
fi
[root@master ~]# ./test.sh 2
>1
[root@master ~]# ./test.sh 1
=1
[root@master ~]# ./test.sh 0
<1
[root@master ~]# cat test.sh
#!/bin/bash

if  [ $1 -gt 1 ];then
   echo '>1'
elif [ $1 -lt 1 ];then
    echo '<1'
else 
    echo '=1'
fi
#与python类似

也可以使用逻辑运算符实现

condition && action  //如果condition为真则执行action
condition || action    //如果condition为假则执行action
[root@localhost ~]# touch 123
[root@localhost ~]# ls
123  anaconda-ks.cfg  
[root@localhost ~]# mkdir 123
mkdir: 无法创建目录"123": 文件已存在
[root@localhost ~]# mkdir 123 || rm -f 123
mkdir: 无法创建目录"123": 文件已存在
[root@localhost ~]# ls
anaconda-ks.cfg  logs  


[root@localhost ~]# mkdir 123 && touch 123/456
[root@localhost ~]# ls 123
456

2. 模式匹配:case

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

//case支持glob风格的通配符:
    *           //任意长度任意字符
    ?           //任意单个字符
    []          //指字范围内的任意单个字符
    abc|bcd     //abc或bcd
 
[root@master ~]# ./case.sh 1
you input 1
[root@master ~]# ./case.sh 2
you input 2
[root@master ~]# ./case.sh 3
you input 3
[root@master ~]# ./case.sh 6
 errro
[root@master ~]# cat case.sh 
#!/bin/bash

case $1 in 
1)
 echo 'you input 1'
;;
2)
echo 'you input 2'
;;
3)
echo 'you input 3'
;;
*)
echo ' errro'
;;
esac 

3. 循环语句

shell中有3种循环语句

  • for
  • while
  • until
    循环语句通常需要有一个进入条件和一个退出条件。
    死循环只有进入条件

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@master tmp]# ./for.sh
=====================
sshd:x:74:74:Privilege-separated
=====================
SSH:/var/empty/sshd:/sbin/nologin
=====================
avahi:x:70:70:Avahi
=====================
mDNS/DNS-SD
=====================
Stack:/var/run/avahi-daemon:/sbin/nologin
=====================
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
=====================
tcpdump:x:72:72::/:/sbin/nologin
=====================
l:x:1000:1000:l:/home/l:/bin/bash
=====================
mysql:x:988:982::/home/mysql:/sbin/nologin
=====================
tom:x:1001:1001::/home/tom:/bin/bash
=====================
[root@master tmp]# cat for.sh 
#!/bin/bash
echo =====================
for line in $(cat /tmp/passwd);do
echo $line 
echo =====================
done

也可以

[root@master tmp]# ./for.sh
=====================
sshd: 
=====================
SSH: 
=====================
avahi: 
=====================
mDNS/DNS-SD: 
=====================
Stack: 
=====================
postfix: /sbin/nologin
=====================
tcpdump: /sbin/nologin
=====================
l: /bin/bash
=====================
mysql: /sbin/nologin
=====================
tom: /bin/bash
=====================
[root@master tmp]# cat for.sh 
#!/bin/bash
echo =====================
for line in $(cat /tmp/passwd);do
echo $line | awk -F: '{print $1": "$7}'
echo =====================
done
[root@master ~]# ./for1.sh
1
2
3
4
5
6
7
8
9
10
[root@master ~]# cat for1.sh 
#!/bin/bash
for ((i=1;i<=10;i++))
{
echo $i
}

等同于

[root@master ~]# ./for1.sh 
1
2
3
4
5
6
7
8
9
10
[root@master ~]# cat for1.sh 
#!/bin/bash
for i in {1..10};do

echo $i
done

还可以

[root@master ~]# ./for1.sh 
1
2
3
4
5
6
7
8
9
10
[root@master ~]# cat for1.sh 
#!/bin/bash
for i in $(seq 10);do

echo $i
done

批量创建用户

[root@master ~]# ./for1.sh 
useradd:用户“user1”已存在
 user1 创建成功。
useradd:用户“user2”已存在
 user2 创建成功。
useradd:用户“user3”已存在
 user3 创建成功。
useradd:用户“user4”已存在
 user4 创建成功。
useradd:用户“user5”已存在
 user5 创建成功。
useradd:用户“user6”已存在
 user6 创建成功。
useradd:用户“user7”已存在
 user7 创建成功。
useradd:用户“user8”已存在
 user8 创建成功。
useradd:用户“user9”已存在
 user9 创建成功。
useradd:用户“user10”已存在
 user10 创建成功。
[root@master ~]# cat for1.sh 
#!/bin/bash
for ((i=1;i<=10;i++));do
   useradd  user$i
   id user$i &>/dev/null
   if [ $? -eq 0 ];then
      echo " user$i 创建成功。"
    fi
done

批量删除

[root@master ~]# ./for1.sh 
 user1 删除成功。
 user2 删除成功。
 user3 删除成功。
 user4 删除成功。
 user5 删除成功。
 user6 删除成功。
 user7 删除成功。
 user8 删除成功。
 user9 删除成功。
 user10 删除成功。
[root@master ~]# cat for1.sh 
#!/bin/bash
for ((i=1;i<=10;i++));do
   userdel -r user$i
   id user$i &> /dev/null
   if [ $? -ne 0 ];then
      echo " user$i 删除成功。"
    fi
done

3.2 while循环

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

while 条件; do
    statement //语句
    ...
done
[root@localhost ~]# cat test.sh
#!/bin/bash

i=10

while [ $i -le 10 -a $i -ge 1 ];do
  echo $i
  let i-=1
done 
[root@localhost ~]# bash test.sh 
10
9
8
7
6
5
4
3
2
1

也可以写为

[root@localhost ~]# cat test.sh 
#!/bin/bash

i=10

while [ $i -gt 0 ];do
  echo $i
  let i--
done 

3.2.2 while循环特殊用法

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

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

while循环特殊用法二:逐行读取某文件,将值存入line变量中
while read line;do
    statement
    ...
done < /path/to/somefile
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
-----------------------
avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin
-----------------------
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
-----------------------
tcpdump:x:72:72::/:/sbin/nologin
-----------------------
l:x:1000:1000:l:/home/l:/bin/bash
-----------------------
nginx:x:988:982::/home/nginx:/sbin/nologin
-----------------------
[root@localhost ~]# cat line.sh 
#!/bin/bash

while read line;do
echo $line
echo -----------------------
done < /etc/passwd

可以对取出的行做处理

gnome-initial-setup 989
-----------------------
sshd 74
-----------------------
avahi 70
-----------------------
postfix 89
-----------------------
tcpdump 72
-----------------------
l 1000
-----------------------
nginx 988
-----------------------
[root@localhost ~]# cat line.sh 
#!/bin/bash

while read line;do
echo $line | awk -F: '{print $1 ,$3}' 
echo -----------------------
done < /etc/passwd

3.3 until循环

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

until 条件; do
    statement
    ...
done

3.4 循环语句特殊情况

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

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

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

4. 函数

在shell 中有两种定义函数的语法格式,分别为:

    函数名()
    {
      命令
      }

   或者:

    function 函数名()    
     {
      命令
      }
[root@localhost ~]# ./lxmp.sh 
123
[root@localhost ~]# cat lxmp.sh 
#!/bin/bash

hanshu () {   //定义函数
echo 123
}

hanshu     //使用函数


[root@localhost ~]# ./lxmp.sh 
4567
[root@localhost ~]# cat lxmp.sh 
#!/bin/bash

function  abc () {
echo 4567
}
abc
//函数名字的定义有一定要求,例如不能用纯数字,要与变量区别开等

5. 定义脚本退出状态码

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

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

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

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

在通配符中*可以匹配任意的0个或多个字符,而在正则表达式中他是重复之前的一个或者多个字符

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值