循环
- 循环执行
将某代码段重复运行多次
重复运行多少次:
循环次数事先已知
循环次数事先未知
有进入条件和退出条件
- for, while, until
for循环
for 变量名 in 列表;do
循环体
done
- 执行机制:
- 依次将列表中的元素赋值给“变量名”; 每次赋值后即执 行一次循环体; 直到列表中的元素耗尽,循环结束
[root@centos7 ~]# type for
for is a shell keyword
[root@centos7 ~]# help for
for: for NAME [in WORDS … ] ; do COMMANDS; done 有多少WORDS就执行多少遍
例子:
#!/bin/bash
for num in 1 2 3 4
do
echo “num is $num”
done
for循环
- 列表生成方式:
(1) 直接给出列表
(2) 整数列表:
(a) {start..end}
(b) $(seq [start [step]] end)
(3) 返回列表的命令
$(COMMAND)
(4) 使用glob
如:*.sh
(5) 变量引用
$@, $*
[root@centos7 ~]# for i in {1..5};do echo i=$i;done
i=1
i=2
i=3
i=4
i=5
[root@centos7 ~]# for i in {3..1};do echo i=$i;done
i=3
i=2
i=1
[root@centos7 ~]# for i in {10..2..2};do echo i=$i;done
i=10
i=8
i=6
i=4
i=2
{10..2..2}表示从10到2,每次递减2
在命令行中用一句话写出的循环
[root@centos7 ~]# sum=0;for i in {2..100..2};do let sum=sum+i;done;echo $sum
2550
[root@centos7 ~]# sum=0;for i in {2..100..2};do sum=$[sum+i];done;echo $sum
2550
[root@centos7 ~]# sum=0;for i in {2..100..2};do sum=$((sum+i));done;echo $sum
2550
1-100中所有被3整除的数字相加的和
[root@centos7 ~]# sum=0;for i in {3..100..3};do sum=$[sum+i];done;echo $sum
1683
1-100中所有不能被3整除的数字相加的和
[root@centos7 ~]# n=6; yu=$[n%3] && echo $yu
0
[root@centos7 ~]# n=10; yu=$[n%3] && echo $yu
1
[root@centos7 ~]# n=5; yu=$[n%3] && echo $yu
2
#!/bin/bash
sum=0
for i in {1..100}; do
yu=$[i%3]
if [ “$yu” -ne 0 ];then
let sum+=i
fi
done
echo $sum
[root@centos7 ~]# seq 1 3 10
1
4
7
10
[root@centos7 ~]# seq 10 -3 1
10
7
4
1
使用命令生成列表
[root@centos7 ~]# for filename in `ls /root/*`;do echo filename is $filename;done
[root@centos7 ~]# for filename in ~ding/*;do echo filename is $filename;done
[root@centos7 ~]# for filename in `ls ~ding/*.sh`;do echo filename is $filename;done
filename is /home/ding/123.sh
生成随机口令
[root@centos7 ~]# openssl rand -base64 8 | head -c8
U3MVFx2u
[root@centos7 ~]# cat /dev/urandom |tr -dc ‘a-zA-Z0-9’ | head -c8
uilsP92K
网络扫描脚本实现
系统信息扫描
[root@centos7 ~]# nmap -v -A 172.18.16.152
#!/bin/bash
> /app/ip.log
#read -p ‘place input you want scan network IPv4‘s address ‘ net
net=172.18.0
for i in {1..254};do
{
if ping -c1 -w1 $net.$i &> /dev/null;then
echo $net.$i is up
echo $net.$i >> /app/ip.log
else
echo $net.$i is down
fi
}&
done
wait
添加10个用户user1-user10,密码为8位随机字符
创建用户
[root@centos7 ~]# cat user.sh
#!/bin/bash
for i in `seq 1 100`; do
username=user$i
useradd $username
password=`openssl rand -base64 32 | head -c 8`
echo $password | passwd $username –stdin &> /dev/null
echo $username $password >> password.log
done
echo ‘finish’
删除用户
[root@centos7 ~]# cat userdel.sh
#!/bin/bash
for i in {1..100};do
username=user$i
userdel -r $username
done
随机数
[root@centos7 ~]# cat /dev/urandom | tr -dc ‘a-zA-Z0-9’ | head -c8
JCtRNFJj
[root@centos7 ~]# openssl rand -base64 32 |head -c 8
wvhX1mG7
while循环
- while CONDITION; do
循环体
done
- CONDITION:循环控制条件;进入循环之前,先做一次判 断;每一次循环之后会再次做判断;条件为“true”,则执行 一次循环;直到条件测试状态为“false”终止循环
- 因此:CONDTION一般应该有循环控制变量;而此变量的值会在循环体不断地被修正
- 进入条件:CONDITION为true
- 退出条件:CONDITION为false
扫描器
扫描httpd服务
#!/bin/bash
sleeptime=30
while true;do
if killall -0 httpd &> /dev/null; then
true
else
systemctl restart httpd
time=`date +’%F %T’`
echo “At $time httpd is restarted” >> /root/httpd_start.log
fi
sleep $sleeptime
done
扫描登录连接数
#!/bin/bash
while read line; do
username=`echo $line | cut-d: -f1`
echo $username | grep -qE “^user[0-9]+$” && userdel -r $username && echo $username is removed
done < /etc/passwd
[root@localhost ~]# vim re_ip.sh
#!/bin/bash
danger=’2′
file=’ip_ad’
sleep_time=60
while true; do
ss -nt | grep “^ESTAB” | tr -s ” ” ‘:’ |cut -d ‘:’ -f 6 | sort | uniq -c >> /root/”$file”
while read num ip;do
if [[ “$num” -gt “$danger” ]] ;then
iptables -A INPUT -s “$ip” -j REJECT
fi
done < /root/”$file”
sleep “$sleep_time”
> /root/”$file”
done
#!/bin/bash
used=3
df -h | grep “/dev/sd” | while read disk ; do
per=`echo $disk | sed -r ‘s/.* (.*)%.*/\1/’`
part=`echo $disk | cut -d” ” -f1`
[ “$per” -gt “$used” ] && echo “$part will be full over ${used}%”
done
显示登录失败的信息
[root@localhost ~]# lastb
root tty1 Tue Dec 19 08:13 – 08:13 (00:00)
root’ tty1 Tue Dec 19 08:13 – 08:13 (00:00)
root tty1 Sat Dec 16 20:13 – 20:13 (00:00)
until循环
- until CONDITION; do
循环体
- done
- 进入条件: CONDITION 为false
- 退出条件: CONDITION 为true
直到条件为真的时候才退出
例子
[root@localhost ~]# vim findccracker.sh
#!/bin/bash
until false; do
sleep 30
pkill -u cracker -9 && echo “at `date +’%F %T’` cracker is killed” >> /root/cracker.log
done
循环控制语句continue
- 用于循环体中
- continue [N]:提前结束第N层的本轮循环,而直接进入下一 轮判断;最内层为第1层
while CONDTIITON1; do
CMD1
…
if CONDITION2; then
continue
fi
CMDn
…
done
循环控制语句break
- 用于循环体中
- break [N]:提前结束第N层循环,最内层为第1层
while CONDTIITON1; do CMD1 …
if CONDITION2; then
break
fi
CMDn
…
done
循环控制shift命令
- shift [n]
- 用于将参量列表 list 左移指定次数,缺省为左移一次。
- 参量列表 list 一旦被移动,最左端的那个参数就从列表中删 除。while 循环遍历位置参量列表时,常用到 shift
- ./doit.sh a b c d e f g h
- ./shfit.sh a b c d e f g h
示例:doit.sh
#!/bin/bash # Name: doit.sh
# Purpose: shift through command line arguments
# Usage: doit.sh [args]
while [ $# -gt 0 ] # or (( $# > 0 ))
do
echo $*
shift
done
示例:
shift.sh
#!/bin/bash
#step through all the positional parameters
until [ -z “$1” ]
do
echo “$1”
shift
done
echo
创建无限循环
while true; do
循环体
done
until false; do
循环体
Done
本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/90571