一、shell脚本的实验
1、计算从1到100所有整数的和
#!/bin/bash
sum=0
for i in {1..100}
do
sum=$(($i+$sum))
done
echo "$sum"
2、提示用户输入一个小于100的整数,并计算从1到该数之间所有整数的和
#!/bin/bash
read -p "请输入一个整数: " num
a=0
for ((i=1;i<=num;i++))
do
let a=$i+$a
done
echo "$a"
3、求从1到100所有整数的偶数和、奇数和
#!/bin/bash
js=0
os=0
for i in {1..100}
do
if [ $(( $i % 2 )) -eq 0 ]
then
let os=$(($i+$os))
else
let js=$(($i+$js))
fi
done
echo "1-100偶数和:$os"
echo "1-100奇数和:$js"
4、用户名存放在users.txt文件中,每行一个,判断文件里的用户是否存在,若该用户存在,输出提示该用户已存在;用户存在但没设密码,则提示用户并让用户设置密码;若该用户不存在,提示用户输入密码,建立用户并设立其密码
#第一步调试一下用户能不能显示
#!/bin/bash
for user in $(cat /opt/users.txt) #用绝对路径
do
echo $user
done
#!/bin/bash
for user in $(cat /opt/users.txt) #用绝对路径
do
grep "^$user:" /etc/passwd >/dev/null #使用grep来过滤查找
if [ $? -eq 0 ]
then
echo "$user已存在"
#定义获取用户的密码字段
passwd=$( grep "$user" /etc/shadow | awk -F: '{print $2}' )
if [ "$passwd" = "!!" ] || [ "$passwd" = "*" ] || [ -z "$passwd" ]
#使用shadow命令里查看的 !! 和 * 是没有密码的字段 -z是查看空字符字段
then
echo "$user用户密码为空.需要设置密码..."
while true #死循环
do
read -p "请输入$user用户的密码: " i
read -p "请再次输入$user用户的密码: " a
if [ "$i" == "$a" ]
then
echo $i | passwd --stdin $user >/dev/null #设置密码
echo "$user密码设置完毕"
break #执行成功后退出
else
echo "密码输入不一致,请重新输入"
fi
done
fi
else
echo "$user不存在,正在创建用户...."
useradd $user
echo "$user用户已经创建完毕.设置用户密码...."
while true #死循环
do
read -p "请输入$user用户的密码: " i
read -p "请再次输入$user用户的密码: " a
if [ "$i" == "$a" ]
then
echo $i | passwd --stdin $user >/dev/null #设置密码
echo "$user密码设置完毕"
break
else
echo "密码输入不一致,请重新输入"
fi
done
fi
done
5、检测指定范围主机是否通信,并将通信的主机ip输出到文件host_ip中
如果执行脚本时间过长可以杀掉进程
ps aux #查看进程
kill 序列号 #杀掉进程
#!/bin/bash
for ip in 192.168.102.{1..254}
do
{
ping -c 3 -i 0.5 -w 2 $ip &> /dev/null
if [ $? -eq 0 ]
then
echo "$ip 存活" >> /opt/ip_yes.txt
else
echo "$ip 不存活" >> /opt/ip_no.txt
fi
}&
done
6、用户输入密码,脚本判断密码是否正确,正确密码为123456,输入正确提示正确信息,连续输错3次则报警
num=123456
for ((i=1;i<=3;i++))
do
read -p "请输入一个密码:" a
if [ "$num" == "$a" ]
then
echo "密码输入正确"
exit
else
echo "密码输入错误,请重新输入"
fi
done
echo "报警"
7、使用循环语句将一个 0到255 之间的十进制数转换成8位数二进制数
1、除二取余倒排法
#!/bin/bash
read -p "请输入一个0~255的整数" num
for i in {1..8}
do
a=$[ num % 2 ]$a #取余数,结果拼接到a前,完成余数倒排
let num=$[num / 2] #将num除二,进入下一个循环
done
echo $a
2、减法正排法
read -p "输入0-255整数" num
for i in {128,64,32,16,8,4,2,1}
do
NUM=$[num - i] #NUM作为预判断变量,先不对num直接处理
if [ $NUM -lt 0 ] #判断是否能减进
then
echo -n 0 #减不进输出0,不对num处理,进入下一轮循环
else
echo -n 1 #能减进输出1 # -n不换行输出
num=$[num-i] #能减进输出则对num减去i,再进入下一轮循环
#let num-=i #与上句同译
fi
done
echo '' #换行
8、编写能够自动生成一个6位随机密码的脚本
str=abc123456
for i in {1..6}
do
a=$[RANDOM % ${#str}]
tmp=${str:a:1}
passwd=$passwd$tmp
done
echo "生成6位数的随机密码为:$passwd "
9、编写能够按照每100行分割文件的脚本
a=0 #定义记录行数的变量
b=1 #定义分割的文件序号表示
IFS_OLD=$IFS #保存原来的值
IFS=$' \n' #改分割符
for i in $(cat anaconda-ks.cfg) #读取文件
do
let a++
#a满100行c即可整除为0,进入if判断第一行。未满100进入if判断第二行
c=$[a % 100]
if [ $c -eq 0 ]
then #满20句写入文件后,标识符b+1,下一次写入不同标识符的新文件
echo $i >> ks.cfg-$b
let b++
else #不满20句的话写入当前文件,标识符不动,下一次仍然写入这个文件
echo $i >> ks.cfg-$b
fi
done
IFS=$IFS_OLD #恢复原来的值
IFS配置,在脚本里修改
set | grep IFS #修改IFS配置
IFS_OLD=$IFS #保存IFS配置到IFS_OLD以便恢复
IFS=$'\n' #设置IFS='\n',即将IFS=$' \t\n'的空格、制表位删除,只保留换行为分隔符
10、将一个点分十进制格式的IP地址转换成点分二进制格式比如 255.255.255.255 -->11111111.11111111.11111111.11111111
#!/bin/bash
read -p "请输入一个ip地址: " ip
b=0 #点计数标识,用于下方重新组合ipv4地址时计数生成了几个点
IFSB=$IFS
IFS=$IFS'.' #临时修改IFS 添加分隔符 . 用于分隔ip地址每一段。
for num in `echo $ip` #`echo $ip`,写在双撇号内,表示显示ip,传递给for以获取ip的每一段
do
#↓↓↓二进制转换↓↓↓#
for i in {128,64,32,16,8,4,2,1} #余数正排法
do
NUM=$[$num - $i] #先不对num操作,用NUM预执行减法,用以判断是否能够减去
if [ $NUM -lt 0 ]
then
echo -n "0" #不能减去不换行输出0
else
echo -n "1" #能减去不换行输出1
num=$NUM #并且对num进行减去操作。(num=$NUM相当于num-=i)
fi
done
#↑↑↑二进制转换↑↑↑#
#↓↓↓IP地址重组合↓↓↓#
let b+=1 #每段IP地址经过二进制转换后都在后方重新添加 .
if [ $b -lt 4 ] #添加一次.标识b增加一次,当标识b计数4次后(加了3个点)停止加点
then
echo -n "." #不换行输出 .
fi
#↑↑↑IP地址重组↑↑↑#
done
echo
IFS=$IFSB #改回IFS
11、假设/opt/test/ 目录中有多个重要文件,编写脚本使用 md5sum 命令一次性判别目录中的文件是否有发生过改动
#!/bin/bash
for file in $(ls /opt/test) #遍历文件夹文件,写绝对路径
do
SUM_NOW=$(md5sum /opt/test/$file | awk '{print $1}')
#使用md5sum对文件生成md5信息,md5共有数据与文件名两段,取第一段
SUM_OLD=$(grep $file /root/md5sum.txt | awk '{print $1}')
#从之前生成的md5存储文件中获取当前文件的md5信息,取第一段数据
if [ "$SUM_NOW" != "$SUM_OLD" ] #判定md5是否相同
then
echo "$file 文件被改动"
fi
done
12、输出环境变量PATH的目录所包含的所有可执行文件
#!/bin/bash
IFSB=$IFS
IFS=$IFS':'
#由于系统变量用:分隔,IFS需要临时添加:分隔符。
#但是不能只设置: 这样会导致识别不了其他的分隔符而导致下方路径拼接错误
#这里使用$IFS':' 表示在原先IFS设置的基础之上再增加:而不是只有一个:作为分隔符
for folder in $PATH #遍历系统变量中文件夹
do
echo $folder #显示文件夹
for file in $folder/* #遍历文件夹中文件,注意要写全 $folder/* 否则获取的文件为相对路径会导致路径拼接错误
do
if [ -f "${file}" ] && [ -x "${file}" ] #若是文件并且有执行权限才显示
then
echo " $file"
fi
done
done
IFS=$IFSB #恢复IFS设置
另一种写法,指定绝对路径
#!/bin/bash
IFSB=$IFS
IFS=$IFS':'
for folder in $PATH
do
echo $folder
for file in $(ls $folder)
#$(ls $folder)是 $folder/*另一种写法 由于获取绝对路径
do
if [ -f "${folder}/${file}" ] && [ -x "${folder}/${file}" ]
#"${folder}/${file}"是"${file}"另一种写法 用于获取绝对路径
then
echo " $file"
fi
done
done
IFS=$IFSB
13、循环读取文件内容
for a in $(cat 1.txt) #不加cat直接输出只能输出文件名!
do
echo $a
done
while read b
do
echo $b
done < 1.txt #重定向输出
cat 1.txt | while read c #cat管道符号
do
echo $c
done
二、awk 筛选列
[xue@xue ~]$ free -m #查看内存
total used free shared buff/cache available
Mem: 3931 1078 806 86 2046 2509
Swap: 3968 0 3968
[xue@xue ~]$ free -m | grep Mem #筛选MEM
Mem: 3931 1079 806 86 2046 2509
[xue@xue ~]$ free -m | grep Mem |awk '{print $3}'
1079 #再次筛选MEM行第三列
使用多种方法筛选文本(awk,切片)
i='10.11.12.13'
echo ${i:3:2} #从第三位开始切2个字符
echo ${i%%.*} #从后向前删到第一个 .
10
echo ${i%.*} #从后向前删到最后一个 .
10.11.12
echo ${i#*.} #从前向后删到第一个 .
11.12.13
echo ${i##*.} #从前向后删到最后一个 .
13
三、统计斐波拉契数和
输入后使用sh 来验证
a=1
b=1
C=0
for i in {1..10}
do
echo $a
C=$[C+a]
sum=$[a+b]
a=$b
b=$sum
done
echo "sum=$C"