目录
一、命令
1.echo命令
echo -n 表示不换行输出
echo -e 输出转义字符,将转义后的内容输出到屏幕上
常见转义字符:
\b
相当于退格键
转义后相当于退格键(backspace),但是前提是“\b”存在字符。“\b”表示删除前一个字符,“\b\b”表示删除前面两个字符。
\t
制表符显示
转义后表示插入横向制表符,即tab。
\c
不换行输出
不换行输出,在“\c”后面不存在字符的情况下,作用相当于echo -n
,但是当“\b”后面仍然存在字符时,“\c”后面的字符将不会被输出。
\n
换行输出
换行输出,被输出的字符从"\n"处开始另起一行
脚本磁盘自动分区
echo "- - -" > /sys/class/scsi_host/host0/scan;echo "- - -" > /sys/class/scsi_host/host1/scan;echo "- - -" > /sys/class/scsi_host/host2/scan
刷新新加磁盘
可以先看看需要多少次回车,然后在编辑
去编辑脚本:
#!/bin/bash
#自动分区磁盘
read -p "请输入需要分区的设备(例如/dev/sdb):" disk
echo -e "n\n\n\n\n+5G\nw\n"|fdisk $disk
再去查看下:
小插曲:要先选中,选几级标题可以ctrl+几 例如ctrl+1 是一级标题
2.date 查看当前系统时间
-d 你描述的日期,显示指定字符串所描述的时间,而非当前时间
%F 完整日期格式,等价于 %Y-%m-%d
% T 时间(24小时制)(hh:mm:ss)
3. seq
循环语句
循环:将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件
重复运行次数
-
循环次数事先已知
-
循环次数事先未知
常见的循环的命令:for(已知次数) ,while(已知条件), until(已知条件)
二、for 循环语句
(一)for 循环实验及介绍
for 用于已知循环次数的场景
-
用法:
-
读取不同的变量值,用来逐个执行同一组命令
-
for循环经常使用在已经知道要进行多少次循环的场景
-
格式:
for 变量名称 in 取值列表
do
执行内容 若满足循环则做什么动作
done 循环结束标志
for 变量名称(注意是名称不是变量$等) [ in 名称范围 ] (可以不写)
哈哈,网速不好,没加载好
批量修改文件后缀名 sh改名txt
#!/bin/bash
for i in `ls /data`
do
name=`echo ${i} | cut -d"." -f1`
mv /data/${i} /data/${name}.txt
done
把data下的所有文件,改成已.txt 结尾的(最好切换到别的目录,例如opt ,要不会到data下的文件都变成txt)
用for循环求1到100的和
#!/bin/bash
sum=0
for i in {1..100}
do
sum=$[i+sum]
done
echo "100以内的求和结果:$sum"
#i=1 sum =0 sum1=1+0
#i=2 sum =1 sum2=1+2
#i=3 sum =3 sum3=3+3
求1到100奇数和 求1到100偶数和
(面试题哈这是)
#!/bin/bash
#求1到100的和
sum=0
for i in {1..100}
do
sum=$[i+sum]
done
echo "100以内的求和结果:$sum"
#i=1 sum =0 sum1=1+0
#i=2 sum =1 sum2=1+2
#i=3 sum =3 sum3=3+3
echo -e "-----------------------------------------------"
#求1到100奇数和
sum=0
for i in {1..100..2}
do
let sum+=$i
done
echo "100以内的奇数和:$sum"
echo -e "-----------------------------------------------"
#求1到100偶数和
sum=0
for i in {0..100..2}
do
let sum=$[i+sum]
done
echo "100以内的偶数和:$sum"
用 for 写一个a.sh循环脚本
举例:
vim a.sh #创建脚本a.sh
脚本内容:
#!/bin/bash
for i in {1..5} #for循环5次,第一次i=1,第二次i=2以此类推直到i=5
do
echo "$i" #循环动作,每次输出$i
done #for语句结束标志
bash a.sh #调用shell执行脚本a.sh
执行结果:
1
2
3
4
5
批量添加用户
实验目的:
#!/bin/bash
for i in `cat /data/name.txt`
do
id $i &>/dev/null
if [ $? -eq 0 ]; then
echo "${i}用户以存在"
else
useradd $i
echo 123456 |passwd --stdin $i &>/dev/null
fi
done
看下 /etc/passwd 是否存在,在文章末尾,也可以cat /etc/passwd |tail看
因为刚才已经创建了 name.txt 里面的用户,所以无法再次创建
ping一整个网段(192.168.246段为例)
方法一:
#!/bin/bash
for i in {1..254}
do
{
ping -c2 -W2 192.168.246.$i &>/dev/null && echo "$i is online" >> /data/hostonline.txt || echo "$i is offlin
e" >> /data/hostoffline.txt
} &
done
方法二:
#!/bin/bash
{
for i in {1..254}
do
ping -c2 -W2 192.168.246.$i &>/dev/null
if [ $? -eq 0 ] ;then
echo "host is online" >> /data/on.txt
else
echo "host is offline">> /data/off.txt
fi
done
} &
给文件批量改名 工号_姓名
通过脚本可以批量改变格式
修改后的文件格式
#!/bin/bash
for i in `ls /data02`
do
a=`echo $i |cut -d"_" -f1`
b=`echo $i |cut -d"_" -f2`
mv /data02/$i /data02/${b}_${a}.jpg
done
(二)类似于C语言风格的for循环
for ((expr1;expr2;expr3))
do
command
done
expr1:定义变量并赋初值
expr2:决定是否循环
expr3:决定循环变量如何改变,决定循环什么时候退出
sum+=i 等于 sum=sum+i
#需要使用 let 命令
++ 自身变量+1
-- 自身变量-1
+=5 自身变量+5
-=5 自身变量-5
*=5 自身变量*5
/=5 自身变量/5
%=5 自身变量%5
用for循环脚本求1到100的和
#!/bin/bash
sum=0
for ((i=0;i<=100;i++))
do
sum=$[sum+i]
done
echo "输出1到100的和: $sum"
sum=0 #赋予sum变量最初值
for ((i=0;i<=100;i++))
#i=0:变量初始值,先决条件
#i<=100:判断条件;i小于等于100,如果不正确,直接退出
#i++:变量自身+1
#这条信息的意思是,每次调取这个变量时,都会迭代生成新的+1数值,一直到100结束
do
sum=$[sum+i] #在每次循环中,将当前数值i加到变量sum上
done
echo $sum
(三)循环打印9*9乘法表
①第一步for循环打印一行9个*号
②第二步再添加一个for循环打印一个9行9列的*号正方形
②第三步将*号正方形斜砍一般形成9*9乘法表的基本格式
③第四步将*号9*9乘法表格式用乘法算式替换
9*9乘法表
第一步:
vim 99.sh #创建99.sh脚本
脚本内容:
#!/bin/bash
for i in {1..9} #for循环9次从i=1开始
do
echo -n "*" #每循环一次打印一个*,echo -n参数表示不换行
done #此for循环语句结束
bash 99.sh #调用shell执行脚本
执行结果:
*********
第二步:
vim 99.sh #编辑99.sh脚本
脚本内容:
#!/bin/bash
for j in {1..9} #添加打印列循环,循环9次从j=1开始
do #j循环时做do中的内容
for i in {1..9} #第一步for循环内容不变
do
echo -n "*"
done
echo #列循环每循环一次打印一行空格进行换行
done #列循环for语句结束标志
bash 99.sh #调用shell执行脚本
执行结果:
*********
*********
*********
*********
*********
*********
*********
*********
*********
第三步:
vim 99.sh #编辑99.sh脚本
脚本内容:
#!/bin/bash
for j in {1..9} #列循环内容不变
do
for i in `seq $j` #修改行循环i的取值范围为展开变量j,即当j=1时i取值只有1,所以循环一次。当
j=2时,i取值为1和2,所以i=1和i=2各循环一次,循环2次。以此类推到j=9
do
echo -n "*"
done
echo
done
bash 99.sh #调用shell执行脚本
执行结果:
*
**
***
****
*****
******
*******
********
*********
第四步:
vim 99.sh #编辑99.sh脚本
脚本内容:
#!/bin/bash
for j in {1..9} #列循环内容不变
do
for i in `seq $j`
do
echo -ne "$j*$i=$[ $j*$i ]\t" #行输出内容修改为9*9算式和结果。$[ ]表示计算里面的正整数结
果,echo -e参数表示调用转义符,\t表示制表符即循环时输出一个tab键
done
echo
done
bash 99.sh #调用shell执行脚本
输出结果:
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
9*9乘法表 倒打印
一个正着打印,一个倒打印
#!/bin/bash
for j in {1..9}
do
for i in `seq $[10-$j]`
do
echo -ne " ${i}x`echo $[10-j]`=$[(10 -j)*i]\t"
done
echo
done
echo -e "------------------------------------------"
#!/bin/bash
for j in {9..1..-1}
do
for i in `seq $[10-$j]`
do
echo -ne " ${i}x`echo $[10-j]`=$[(10 -j)*i]\t"
done
echo
done
三、 while 循环语句
-
用法:
- 重复测试某个条件,只要条件成立则反复执行
- 常在不知道范围的时候成立
while 条件语句用于重复测试某个条件,当条件成立时则继续重复执行
我们只知道停止条件,不知道次数,就需要使用while直到达到条件
while循环一般用于有条件判断的循环,若判断条件为真,则进入循环,当条件为假就跳出循环
while循环可以不断的执行某个程序,直到用户设置的条件完成为止,所以重点是条件,这种不定循环最常见的就是下面这两种格式了。
1.格式:
while循环:while的中文是【当…时】,所以这种方式说的是,当判断式/命令序列的条件成立时,就进行循环,直到命令序列/程序段落的条件不成立才停止。
原理:
格式:
while 判断条件
do
命令1
done
#语法与if相似
while [ 判断条件] #使用while循环满足条件执行do,不满足不执行
do
执行动作 # while循环执行动作
done #while循环结束标志
1.死循环
在Shell脚本中,while 死循环是指一个 while 循环结构,其条件始终为真,导致循环体内的命令会无限重复执行,除非外部干预
(如通过 Ctrl+C 终止程序或在循环体内使用 break、exit等语句跳出循环)
死循环有三种如下:
1 while 条件永远为真
2 while : 表示为空,永远为真
3 while true
2.用while 求1到100的和
#!/bin/bash
sum=0 #定义sum变量初始值
i=0 #定义i变量初始值
while [ $i -le 100 ] #while循环,条件为当$1小于等于100时执行
do
sum=$[ i+sum ] #循环执行内容计算i+sum的值重新赋值给i
let i++ #每执行一次循环计算一次变量i自加1
done #while语句结束标志
echo "1-100的累加值为:$sum" #循环完成后输出
3. 批量添加用户
要求:
用户名称以stu开头,按数字顺序进行编号
一共添加20个用户,即stu1、stu2、stu20 初始密码均设为123456
4. 批量删除用户
#!/bin/bash
u=1
while [ $u -le 20 ]
do
userdel -r stu$u
let u++
done
5. 猜商品的价格游戏
实验要求:通过变量RANDOM获得随机数 (脚本中的$RANDOM 是一个随机变量)
提示用户猜测并记录次数,猜中后退出循环
思路:①第一步生成一个随机1-100数字
②第二步使用while循环写一个死循环直到用户猜对才结束循环
③在执行循环的过程中统计循环执行次数并输出
#!/bin/bash
p=`echo $[RANDOM%1000+1]`
time=0
while :
do
read -p "请输入商品的价格(1-1000):" h
let time++
if [ $p -eq $h ]
then
echo "恭喜您猜中了,商品的价格是${h};您一共猜了${time}次"
exit
elif [ $p -gt $h -a $h -le 1000 -a $h -gt 0 ]
then
echo "您猜的价格过低"
elif [ $p -lt $h -a $h -le 1000 ]
then
echo "您猜的价格过高"
else
echo "输入有误,请重新输入"
fi
done
6. 猜数字游戏
#!/bin/bash
pc_num=$[RANDOM%3+1]
count=0
while true
do
read -p "请输入一个数字:" user_num
if [ $user_num -eq $pc_num ]
then
echo "答对啦"
break
elif [ $user_num -gt $pc_num ]
then
echo "您猜的数字太大了"
else
echo "您猜的数字太小了"
fi
let count++
done
echo 你输入的次数为:$count
四、until 循环语句
-
用法: 重复测试某个条件,只要条件不成立则反复执行
-
格式:
until 条件测试操作 do 命令序列 done
原理:
-
1.until死循环
死循环一:
#!/bin/bash
until false
do
command
done
死循环二:
#写一个永远为假的表达式,1等于2这个条件永远为假,所以这个脚本会一直循环下去
until [ 1 -eq 2 ]
do
command
done
2.用until循环求1到100的和
#!/bin/bash
sum=0
i=0
until [ $i -gt 100 ]
do
sum=$[sum+i]
let i++
done
echo "输出1到100的和:$sum"
3.为指定用户发送在线消息
要求:
为指定用户发送在线消息
若用户不在线(未登录系统),则每10分钟试一次,直至用户登录系统后在发送信息
用户名与消息通过位置参数传递给脚本
#!/bin/bash
#判断输出的参数是否满足条件
if [ $# -lt 2 ];then
echo "位置参数不足,请在脚本后添加用户名及需要发送的消息"
exit 1
fi
#判断用户是否存在
if grep "^$1" /etc/passwd &>/dev/null ;then
echo "该用户存在!"
else
echo "该用户不存在!"
exit 1
fi
#判断用户是否在线
until who | grep $1 &> /dev/null
do
echo "该用户不在线!"
sleep 5
done
echo $2 | write $1
xhell里面现在是root用户:
进入虚拟机登录zz用户,去xhell 里发送消息,虚拟机里的用户就可以收到了哦
zz用户回复xhell里的root用户:
xhell里root用户就收到了
五. 跳出循环
continue 和 break 和 exit
-
break跳出单个循环 break n 数字 数字是几代表跳出n层循环
-
continue终止某次循环中的命令,但是不会完全终止命令
-
exit 直接退出脚本
它们的区别:
exit
用于完全退出脚本的执行,而break
和continue
用于控制循环结构。break
用于完全退出当前循环,而continue
用于跳过当前迭代,继续下一次迭代
continue 终止某次循环中的命令,但是不会完全终止命令
#!/bin/bash
for j in {1..3}
do
for i in {1..6}
do
if [ $i -eq 5 ];then
continue
fi
echo i=$i
done
echo "-------------------------------------------------"
done
break跳出单个循环
break 截止到当前为止就结束;
break默认为1;
break n 数字 数字是几代表跳出n层循环
break n 数字 数字是几代表跳出n层循环
将break 设为2时,会直接跳出两层循环(内循环和外循环)因为脚本只有两次循环,所以会直接结束脚本
exit
用于完全退出脚本的执行
六、截取网卡流量
ifconfig ens33|grep "RX pa"|awk '{print$3}'
因为网卡流量是不断变化的 所以每次截取的流量不同
使用死循环实时显示ens33网卡发送的数据包流量
#!/bin/bash
while :
do
echo "本地网卡ens33流量信息如下:"
ifconfig ens33|grep "RX pa"|awk '{print$3}'
ifconfig ens33|grep "RX pa"|awk '{print$3}'
sleep 0.5
done
方法二:
#!/bin/bash
a=`ifconfig ens33|grep "RX pa"|awk '{print$3}'`
while :
do
echo "本地网卡ens33流量信息如下:" $a
sleep 0.5
done