一、shell实现100台服务器的公钥的批量分发;

LLD规划:100台服务器ip为:192.168.42.101-201,root密码:123456
考虑因素:
1.如何创建秘钥
2.检查与服务器之间的通讯
3.分发秘钥

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
[root@backup ~]# cat keypir.sh 
#!/bin/bash
password=123456

#创建秘钥对---(ssh-keygen),写入指定文件
CreateKeyPair(){
ssh-keygen -f /root/.ssh/id_rsa -P "" #-P:创建的秘钥是否设置密码,此处不设置密码。
}

#检查100台服务器网络是否畅通
CHECK(){
ping -c 1 192.168.42.$i &>/dev/null
if [ $? -eq 0 ] #$? 返回为0时,说明网络畅通
then
return 1
else
return 0
fi
}

#分发秘钥
TRACE(){
which sshpass &>/dev/null #确定sshpass是否安装,对方服务器可能没有安装
if [ $? -ne 0 ] #通过which命令判断sshpass是否安装,安装了echo $?则返回0
then #$?不为0时,则说明没有安装
yum install sshpass -y
#sshpass -p $password ssh-copy-id -o StrictKeyHostChecking 192.168.42.$i
sshpass -p $password scp -p -o StrictHostKeyChecking=no /root/.ssh/id_rsa.pub 192.168.42.$i:/tmp/
#使用sshpass工具和-o参数实现避免交互输入yes和密码
#将本地/root/.ssh/id_rsa.pub(生成的秘钥文件),传输到对应服务器上/tmp/目录下,此时不能直接传到/root/.ssh目录下,避免其他机器同样操作覆盖文件。
sshpass -p $password ssh -o StrictHostKeyChecking=no 192.168.42.$i "cat /tmp/id_rsa.pub >> /root/.ssh/authorized_keys"
#ssh连接服务器,将/tmp/下密码文件写如入/root/.ssh/authorized_keys
sshpass -p $password ssh -o StrictHostKeyChecking=no 192.168.42.$i "chmod 600 /root/.ssh/authorized_keys" #修改文件权限
sshpass -p $password ssh -o StrictHostKeyChecking=no 192.168.42.$i "rm -rf /tmp/id_rsa.pub" #由于是秘钥文件,为了安全起见,用完删除

else #如果sshpass工具安装,则直接执行。
#sshpass -p $password ssh-copy-id 192.168.42.$i
sshpass -p $password scp -p -o StrictHostKeyChecking=no /root/.ssh/id_rsa.pub 192.168.42.$i:/tmp/
sshpass -p $password ssh -o StrictHostKeyChecking=no 192.168.42.$i "cat /tmp/id_rsa.pub >> /root/.ssh/authorized_keys"
sshpass -p $password ssh -o StrictHostKeyChecking=no 192.168.42.$i "chmod 600 /root/.ssh/authorized_keys"
sshpass -p $password ssh -o StrictHostKeyChecking=no 192.168.42.$i "rm -rf /tmp/id_rsa.pub"
fi
}

#主函数,调用上方定义的函数,实现功能
MAIN(){
for i in {101..201}
do
CHECK
if [ $? -eq 1 ] #调用CHECK检查网络是否畅通,return=1时(畅通)
then
if [ -f /root/.ssh/id_rsa.pub ] #畅通的话,检查秘钥文件是否存在
then
TRACE #执行TRACE函数,分发秘钥
else
CreateKeyPair #创建秘钥
TRACE #分发秘钥
fi
else #不通时
echo " 192.168.42.$i is unreachable..."

fi
done
}

MAIN

二、设计一个shell 程序;

要求在每天凌晨压缩打包/etc 目录下的所有内容,存放在/root/bak 目录里,且文件名为如下形式yymmdd_etc.tar.gz(yy为年,mm为月,dd为日),该目录保存7天内容;每天凌晨3点增量同步到备份服务器/backup目录下,每周六凌晨3点全量同步到备份服务的/backup目录下;备份服务器/backup下保留一个月的备份文件。
考虑因素:
(1)打包/etc目录,并存放在/root/bak目录里,按要求命名。
(2) /root/backup中只保存7天内容。
(3)增量备份,全量备份。
(4)备份服务器保存一个月文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/bin/bash
#定义变量
back_file_name=`date +%Y%m%d`.tar.gz //文件名
back_file_dir=/root/bak //压缩打包路径
backup_server_user=rsync_backup //备份服务器用户
backup_server_pass=123456 //备份服务器密码
root_pass=123456 //备份主机root密码
backup_server_IP=192.168.42.159 //备份服务器IP
mail_owner=ljwenjie66@163.com //邮箱地址
mail_topic="web data backup" //

data_tar(){ #定义用于压缩函数
[ -d $back_file_dir ] || mkdir -p $back_file_dir #判断/root/bak备份的目录是否存在,不存在就创建。
tar -czf $back_file_dir/$back_file_name /etc/* #将/etc下所有内容进行打包/root/bak/下以时间命名。
}

data_trace(){ #进行增量备份
rsync -avz $back_file_dir $backup_server_user@$backup_server_IP::backup --password-file=/etc/rsync.password
} #rsync将本地/root/bak新增的文件备份到备份主机上
#--password-file中存储了rsync的密码,避免了交互输入密码

data_trace_all(){ #实现全量备份
sshpass -p $root_pass scp -o StrictHostKeyChecking=no -rp $back_file_dir/* root@192.168.42.159:/backup
#sshappss -p 123456 scp -rp $back_file_dir root@192.168.42.138:/backup/
} #sshpass工具实现了自动输入密码
#-o StrictHostKeyChecking参数实现了自动输入yes or no,避免了人机交互
#利用scp将/root/bak下所有内容进行备份,以root身份备份到对应主机的/backup目录下

clean_over_localdata(){ #清除本地7天前的的所有文件
find $back_file_dir -mtime +7 -exec rm {} -rf \;
}

clean_over_remodata(){ #利用ssh连接备份服务器,将服务器中一个月之前的文件删除
sshpass -p $backup_server_pass ssh -o StrictHostKeyChecking=no $backup_server_IP "find /backup/ -mtime +30 -exec rm {} -rf \;"
}

case $1 in
data_tar)
data_tar
;;
trace_all)
data_trace_all
;;
data_trace)
data_trace
;;
clean_over_localdata)
clean_over_lcoaldata
;;
clean_remodata)
clean_over_remodata
;;
*)
echo "please input true paramater..." #如果输入的不是有效参数,则输出*

esac

三、shell开发运维管理工具。

要求:用户交互,当用户输入菜单号时,打印相关内容。
菜单
1. 磁盘分区
2. CPU负载
3. 剩余内存
4. 退出
输入:1
输出:(主机名,系统版本,分区情况)
hostname:
system:系统版本
———分区一———–(分区变量输出)
path:分区一
size:大小
file_os:分区文件系统类型
mount_on:分区挂载点
———-分区二———-
path:分区二
size:大小
file_os:分区文件系统类型
mount_on:分区挂载点
输入:2
输出:
1分钟平均负载:
5分钟平均负载:
15分钟平均负载:
输入:3
输出:
目前可用内存:
可用Swap分区:
输入:4
输出:
Bey…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/bin/bash
while true
do
#格式化输出以下菜单
cat <<EOF
-------------------菜单---------------------
- 1.查看磁盘分区 -
- 2.CPU负载 -
- 3.剩余内存 -
- 4.退出 -
--------------------------------------------
EOF
#接受用户输入的一个值
read -p "请输入你要执行的操作:>>>" num
#实现第一个功能:查看磁盘分区
PART(){
echo "hostname:$HOSTNAME" #获取主机名
echo "system: `cat /etc/redhat-release`" #获取系统内核版本
#定义数组,获取磁盘分区放入其中。
array1=(`lsblk -l |awk '/sd[a-z][0-9]/{print $1}'`) #磁盘名
array2=(`lsblk -l |awk '/sd[a-z][0-9]/{print $4}'`) #大小
array3=(`lsblk -l |awk '/sd[a-z][0-9]/{print $6}'`) #类型
array4=(`lsblk -l |awk '/sd[a-z][0-9]/{print $7}'`) #挂载点
#遍历数组
num=`echo $((${#array1[@]}-1))` #获取数组长度-1的值,给num(这里是3)
for i in `seq 0 $num` #i:0-3
do
#循环输出数组1中0到3位置值
cat <<EOF
---------${array1[$i]}-----------
path: ${array1[$i]}
size: ${array2[$i]}
file_os: ${array3[$i]}
mount_on:${array4[$i]}
EOF
done
}
#实现第二个功能查看cpu负载
LOADING(){ #通过uptime命令和awk,获取平均负载
uptime |awk -F [:,] '{print "一分钟平均负载:",$(NF-2)"\n""五分钟平均分在:",$(NF-1)"\n""十五分钟平均负载:",$NF}'
} #$NF:从最后一列开始取
#实现第三个功能查看内存和swap
MEM(){
var=("目前可用内存:" "可用swap分区:")
n=0
for i in `free -h |awk '/^[^[:space:]]/ {print $4}'` #取出内存和swap,进行遍历
do
echo ${var[$n]} $i #为满足题目要求,(说明+内容),将说明放入数组依次输出+内容
let n++ #n从0开始自加实现数组依次输出
done
}
#利用case语句捕获用户键入的值
#模式匹配成功则执行相应函数
case $num in
1)
PART
;;
2)
LOADING
;;
3)
MEM
;;
4)
exit 0
;;
*)
echo "please input true list..."
esac

done