shell脚本基础知识二

1  shell脚本基础知识

1.1  目录

  • 函数及实战
    • 函数的语法
    • 函数的执行
    • 函数实战
  • for循环语句及实战
    • for循环语法结构
    • for循环案例实战
  • while和until循环语句及实战
    • while循环语法结构
    • until循环语法结构
    • while循环和until循环的区别
    • while循环按行读取文件的方法总结
    • while循环案例实战
  • select 循环语句及实战
    • select循坏语法结构
    • select循坏案例实战
  • 循环控制及状态返回值实战
    • break、continue、exit、return
  • 数组及实战
    • 什么是shell数组
    • 数组的定义
    • 数组的调用
    • 数组的打印及输出
    • 数组案例实战

1.2  函数及实战

1.2.1  函数的语法

方法一:

function 函数名()
{
函数体
}

方法二:

函数名()
{
函数体
}

1.2.2  函数的执行

1.无参数函数

函数名

2.有参数函数

函数名 参数1 参数2 .....

注:函数参数类似于shell脚本的位置参数,$1-$2分别表示提供给函数的第1个参数到第n个参数
$# 参数个数 
$@和$* 为所有参数列表 
$0仍为父脚本的名称

1.2.3  函数实战

案例描述:编写脚本模拟用户密码登录(用户名和密码只能是tom/123),要求:编写input函数:用于判断用户的输入是否为空

思路分析:

1.环境准备
2.解决思路
1)编写输入函数,结合while实现
2)提示输入用户名,如果用户名不是tom,则提示“用户不存在”
否则,提示用户输入密码,如果密码不是123,则提示“密码错误,请重新输入”
否则,提示“登录成功”
3.开发脚本


1
#!/bin/bash
2
#Author:ZhangMiaomiao
3
#Blog:http://blog.csdn.net/moledyzhang
4
#Time:2017-10-10 21:27:24
5
#Name:login.sh
6
#Version:V1.0
7
#Description:
8
fun_input()
9
{
10
    input=""
11
    while [ -z $input ]
12
    do
13
        read -p "$1" input
14
    done
15
    echo $input
16
}
17
username=`fun_input 请输入用户名:`
18
if [ $username = "tom" ];then
19
    password=`fun_input 请输入密码:`
20
    if [ $password != "123" ];then
21
        echo "密码错误,请重新输入"
22
    else
23
        echo "登录成功"
24
    fi  
25
else
26
    echo "该用户不存在"
27
fi
28

执行结果:



1.3  for循环语句及实战

1.3.1  for循环语法结构

1.第一种:变量取值型for循环

for 变量名 in 变量值列表
do
循环体
done

2.第二种:c语言型for循环

for((exp1,exp2,exp3))
do
循环体
done

1.3.2  for循环案例实战

1.输出数字系列 1 2 3 4 5

方法一:直接列出元素法

1
for i in 1 2 3 4 5
2
do
3
    echo $i
4
done
5

方法二:使用{}

In [ ]:
1
for i in {1..5}
2
do
3
    echo $i
4
5
done
6

方法三:使用seq命令

注:"seq m n" 命令用于产生一个数到另一个数之间所有的整数

1
for i in `seq 1 5`
2
do
3
    echo $i
4
done
5

2.批量创建用户tom01到tom10,并设置随机密码(要求为字母和数字的8位组合)

案例分析:
1.环境准备:无
2.思路分析
1).产生数字01到10的方法
方法一:seq -w 01 10
方法二:echo {01..10}
2).创建用户
useradd 用户名 3).设置无交互密码的方法
echo 密码|passwd --stdin 用户名
4).产生随机密码的方法
echo $RANDOM|md5sum|cut -c 3-10 

3.开发脚本


1
user="tom"
2
passwfile="/tmp/user.log"
3
for i in `seq -w 01 10`
4
do
5
    useradd $user$i  #创建用户
6
    passw=`echo $RANDOM|md5sum|cut -c 3-10 ` #因多次使用随机数,所以定义变量保存
7
    echo $passw|passwd $user$i --stdin &>/dev/null #设置密码
8
    echo -e "user:$user$i\tpasswd:$passw">>$passwfile #保存设置的账号和密码信息
9
done
10
cat $passwfile
11

执行结果:



1.4  while和until循环语句及实战

1.4.1  while循环语法结构

while <条件表达式> 
do 
循环体 
done 
条件表达式的位置写true表示条件永远为真

1.4.2  until循环语法结构

until <条件表达式> 
do 
循环体 
done 

1.4.3  while循环和until循环的区别

while循环是满足条件进入循环
until循环是满足条件则退出循环

1.4.4  while循环按行读取文件的方法总结

方法一:利用for循环和cat结合
for line in `cat FILE`
do
echo $line
done


方法二:使用cat读取文件,然后通过管道进入while循环处理
cat FILE|while read line
do
操作
done


方法三:在while循环结尾done处通过输入重定向指定读取的文件
while read line
do
操作
done < FILE

方法四:采用exec读取文件,然后进入while循环处理
exec < FILE 
while read line
do
echo $line
done

1.4.5  while循环案例实战

案例描述:编写一个案例解决防止DDoS攻击的生产案例。请根据web日志或系统连接数,监控某个ip的并发连接数,若短时间内pv达到100,即封掉对应的ip
防火墙命令为:iptables -I INPUT -s IP -j DROP
案例分析:
方法一:分析web日志(这里按每小时为单位进行处理)(实际应用应该根据公司网站业务)
1.环境准备
1)安装nginx
2)日志切割,将日志分成不同的文件
2.分析思路-转换对应的代码
1)分析访问日志,将ip及对应的次数存入文件
awk '{print $1}' /usr/local/nginx/logs/access.log|grep -v '^$'|sort|uniq -c>/tmp/tmp.log 
2)分析文件中的每一行,如果超过100次则封掉
3.开发脚本

1
file=$1
2
awk '{print $1}' $1|grep -v '^$'|sort|uniq -c>/tmp/tmp.log #分析切割后的日志将ip及对应次数存入临时文件
3
exec</tmp/tmp.log
4
while read line
5
do
6
        ip=`echo $line|awk '{print $2}'`
7
        num=`echo $line|awk '{print $1}'`
8
        if [ $num -gt 100 ] && [ `iptables -L -n|grep "$ip"|wc -l` -lt 1 ];then #封掉大于100次的ip
9
            iptables -s $ip -p tcp -I INPUT -j DROP
10
            echo "$ip is dropped ">/tmp/drop_ip_list_$(date +%F).log #记录处理日志
11
        fi
12
done     
13

执行结果:

方法二:分析网络连接数


1
#!/bin/bash
2
check_ddos(){
3
    netstat -antu|grep ESTABLISHED|awk -F '[ :]+' '{print $6}'|sort|uniq -c > ESTABLISHED.log
4
    [ $? -eq 0 ]&&exec < ESTABLISHED.log||exit 1
5
    while read line
6
    do
7
        pv=`echo $line|awk '{print $1}'`
8
        ip=`echo $line|awk '{print $2}'`
9
        if  [ $pv -gt 100 ]&&[ `/etc/init.d/iptables -L -n|grep $ip|wc -l` -gt 0 ];then
10
            iptables -I INPUT -s $ip -j DROP
11
        fi
12
13
    done
14
}
15
16
main(){
17
    while true
18
    do
19
        check_ddos
20
        sleep 3m
21
    done
22
}
23
24
main
25

1.5  select 循环语句及实战

1.5.1  select循环语法结构

select 变量名 [in 菜单值列表]
do
循坏体
done

1.5.2  select循环案例实战

案例描述:打印选择菜单,安装选择一键安装不同的服务,菜单效果如下:_auto_0脚本:

1
select var in "Install lamp" "Install lnmp" "exit"
2
do
3
        case $var in
4
        "Install lamp")
5
            echo "starting install lamp";;
6
        "Install lnmp")
7
            echo "starting install lnmp";;
8
        "exit")
9
            echo "Bye"
10
            exit;;
11
        *)
12
            echo "input error,must be input {1|2|3}";;
13
        esac
14
15
done
16
17

1.6  循环控制及状态返回值实战

1.6.1  break、continue、exit、return对比


1.7  数组及实战

1.7.1  什么是shell数组

简单说,shell数组就是一个元素集合,它把有限个元素(变量或字符内容)用一个名字来命名,然后对它们进行区分。这个名字就是数组名,用于区分不同内容的编号就被称为数组的下标或索引。组成数组的每个变量或字符被称为数组的元素。

1.7.2  数组的定义

方法一:
数组名=(值1 值2 值3…)
例子
array=(tom jack rose)空格隔开的字符串依次赋值给数组每个元素
array=([0]=tom [1]=jack [2]=rose [6]=natasha)
方法二:
array=([1]=tom [2]=lucy [3]=alice)
方法三:(下标可以不连续)
array[0]="tom"
array[1]="jack"
array[2]="rose"
array[6]="natasha" 注:7个元素0-6,中间未赋值的为空

1.7.3  数组的调用

${数组名[下标值]}

在数组中可以使用*或@符号来代替下标,此时*或@为通配符,所以可以用array[*]或array[@]数组中的所有元素
数组中元素个数:${#array[*]}或者${#array[@]} 注:是非空元素个数
数组中单个元素的长度:${#array[n]},其中n为元素下标

1.7.4  数组的打印及输出

1.打印数组元素


2.数组的赋值


3.数组中元素的删除


4.数组内容的截取和替换 截取


删除数组元素部分内容


5.数组的删除

1.7.5  数组案例实战

案例描述:使用数组方法打印下面这段话中单词数不大于6的所有单词
i am a bw teacher welcome to beijing bw
1.解决思路:
1).先将所有单词存入数组 array=(i am a bw teacher welcome to beijing bw)

2).计算数组中每个元素的长度



3).如果不大于6则打印该单词

2.开发代码:

1
array=(i am a bw teacher welcome to beijing bw)
2
for word in ${array[*]}
3
do
4
        if [ ${#word} -lt 6 ];then
5
            echo $word
6
        fi
7
done
8
9
            

执行结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值