60天shell脚本计划-3/12-渐入佳境
阅读原文时间:2023年07月09日阅读:3

--作者:飞翔的小胖猪

--创建时间:2021年2月6日

--修改时间:2021年2月10日

说明

每日上传更新一个shell脚本,周期为60天。如有需求的读者可根据自己实际情况选用合适的脚本,也可在评论区留言提出脚本需求,作者会尽快根据需求编写相关脚本对功能进行实现。

每篇文章包含5个脚本。

总进度:3/12

上一篇脚本链接:https://www.cnblogs.com/Pigs-Will-Fly/p/14356727.html

下一篇脚本链接:https://www.cnblogs.com/Pigs-Will-Fly/p/14399775.html

主要内容

************************************************************************************************************************************************************************************************************************************

脚本说明

用户登录操作操作系统后,根据登录来源、用户名、登录时间为名生成一个文件。记录用户至登录系统以来执行得所有命令实时的写入到生成的文件中。

该记录文件在创建过后只能追加无法删除,同时保存命令执行记录的文件加。

用户使用时在/etc/profile文件最后添加 source /绝对路径/User_Command_History.sh

文件说明

User_Command_History.sh:脚本主体文件

脚本主体

[root@135 11_User_Command_History]# cat User_Command_History.sh
#!/bin/bash
create_save_dir(){
#创建保存文件的路径,设置所有人都可以访问但是不能删除文件只能创建文件。
if [ -d /var/log/audit_command/ ];then
chattr -a /var/log/audit_command/
chmod 777 -R /var/log/audit_command/ &>/dev/null
chattr +a /var/log/audit_command/ &>/dev/null
echo "save log dir exits." &>/dev/null
else
mkdir -p /var/log/audit_command/ &>/dev/null
chown -R nobody.nobody /var/log/audit_command/ &>/dev/null
chmod 777 -R /var/log/audit_command/ &>/dev/null
chattr +a /var/log/audit_command/ &>/dev/null
fi
}

save_info_to_file(){
#把脚本中的变量赋值给系统的PROMPT_COMMAND和file_dir值。
#设置命令格式为: 时间+用户+路径+命令
#设置命令历史保存路径为自动生成的文件
echo "file dir values: ${file_name}"
export HISTTIMEFORMAT='%F %T'" "
export HISTSIZE=10000
#设置记录所有命令包括重复的
export HISTCONTROL=""
export HISTFILE="/var/log/audit_command/${file_name}"
PROMPT_COMMAND="history -a"
}

Generate_File(){
#获取系统全局变量
login_ip=`echo "${SSH_CLIENT:-127.0.0.1}" | awk '{print $1}'`
login_date=`date "+%Y-%m-%d_%H:%M:%S"`
login_user=${LOGNAME:-root}
file_name="${login_ip}_${login_user}_${login_date}.log"
#创建文件
touch /var/log/audit_command/${file_name} &>/dev/null
chown nobody.nobody /var/log/audit_command/${file_name} &>/dev/null
chattr +a /var/log/audit_command/${file_name} &>/dev/null
echo "Operation log function enabled,Save file to /var/log/audit_command/${file_name}"
}

main(){
create_save_dir
Generate_File
save_info_to_file
echo "该session执行命令从这里开始-----start------- " >>/var/log/audit_command/${file_name}
}

main

结果

登录展示

实时文件

**************************************************************************************************************2021年2月6日脚本结束*****************************************************************************************************************

************************************************************************************************************************************************************************************************************************************

脚本说明

脚本通过定时任务周期运行,判断指定目录的大小和文件创建时间,如果文件夹占用空间在10M以上,则删除1天前创建的文件,并记录删除列表。

读者在使用请根据自己的具体环境选择调用 自动清除函数 还是手动确认函数。

再执行删除文件操作时请多次确认避免误操作,尤其对于周期性任务更需要多次检查脚本任务的正确性。

文件说明

clear_space.sh:脚本主体文件

脚本主体

[root@135 12_Clear_files_at_regular_intervals]# cat clear_space.sh
#!/bin/bash
get_dir_storage(){
#判断是否输入目录名,如果没有输入则适用null
dir_name=${1:-null}
if [ $dir_name == "null" ];then
echo "ERROR: Please input dir name。"
echo -e 'clear_space: usage: clear_space '
exit 1
elif [ -d ${dir_name} ];then
echo "The correct folder path : ${dir_name} "
#获取目录的占用空间大小,单位为KB
dir_size=`du -s ${dir_name}|grep ${dir_name}$|awk '{printf $1}'`
else
echo "ERROR: Please input dir name。"
echo -e 'clear_space: usage: clear_space '
exit 1
fi
}

#删除前手动确认,用来手动执行时。
manual_clear_file(){
if [ ${dir_size:-0} -gt 10240 ];then
echo "This dir : $dir_name total size : ${dir_size} More than 10 MB"
#选择是否清除目录下的文件,敲了yes就会删除所有符合条件的文件。.
read -p "Please confirm whether to delete the file. Input yes(n) or no(n): " ask_an
if [ -z "${ask_an}" ];then
echo "Not values exit。"
elif [ ${ask_an} == yes ] || [ ${ask_an} == y ];then
echo "Perform the delete file operation"
find ${dir_name} -mtime +1 -name "*.log" > tmp_Delete_file_list.txt
find ${dir_name} -mtime +1 -name "*.log" -exec rm {} \;
elif [ ${ask_an} == no ] || [ ${ask_an} == n ];then
echo "exit clear program。"
fi
else
echo "This dir : $dir_name total size : ${dir_size} Less than 10 MB"
fi
}

#不用确认直接删除,用在周期脚本中。
auto_clear_file(){
if [ ${dir_size:-0} -gt 10240 ];then
echo "This dir : $dir_name total size : ${dir_size} More than 10 MB"
find ${dir_name} -mtime +1 -name "*.log" > tmp_Delete_file_list.txt
find ${dir_name} -mtime +1 -name "*.log" -exec rm {} \;
else
echo "This dir : $dir_name total size : ${dir_size} Less than 10 MB"
fi
}

clear_static(){
file_rows=`cat tmp_Delete_file_list.txt|wc -l`
if [ ${file_rows:-0} -eq 0 ];then
echo " `date` not delete any files" >> /var/log/message
else
echo " `date` delete ${file_rows} files" >> /var/log/message
fi
echo -e "A list of all files that have been deleted:\nTotal Delete files: ${file_rows}\n___________________________________________\n`cat tmp_Delete_file_list.txt`\n___________________________________________" >> /var/log/message
echo -e "A list of all files that have been deleted:\nTotal Delete files: ${file_rows}\n___________________________________________\n`cat tmp_Delete_file_list.txt`\n___________________________________________"
rm -rf tmp_Delete_file_list.txt &>/dev/null
}

main(){
get_dir_storage $1
manual_clear_file
clear_static
}

main $1

结果

执行命令结果

日志文件结果

**************************************************************************************************************2021年2月7日脚本结束*****************************************************************************************************************

************************************************************************************************************************************************************************************************************************************

脚本说明

脚本定时扫描系统中存在的xfs、ext3、ext4格式的挂载点判断其剩余空间大小,如果使用率大约98%同时空间小于1GB则自动运行扩容操作。

每次自动扩容空间为2GB。

对于标准分区则通过发送邮件的方式提示相关运维人员处理,脚本不自动进行扩容。

文件说明

auto_check_and_add_space.sh:脚本主体文件

脚本主体

[root@135 13_Auto_add_space]# cat auto_check_and_add_space.sh
#!/bin/bash

#扫描是否存在新磁盘
Scan_new_disk(){
for i in `ls /sys/class/scsi_host/`
do
echo '- - -' > /sys/class/scsi_host/${i}/scan &>/dev/null
done
}

#判断文件ext3 ext4 xfs挂载点空间剩余是否能够触发扩容操作,返回0表示又需求,返回1表示不满足情况。排除/boot挂载点
#结果置入到second_tmp_df.txt文件中。
System_check_space(){
#初始化临时文件

tmp_df.txt
second_tmp_df.txt
df -TPh -B 1M --type=xfs -t ext2 -t ext4 -t ext3 |grep -vE '^Filesystem|tmpfs|cdrom|boot'| sed 's/\%//g' >> tmp_df.txt
#df -TPh -B 1M --type=xfs -t ext2 -t ext4 -t ext3 |grep -vE '^Filesystem|tmpfs|cdrom'| sed 's/\%//g' >> tmp_df.txt
cat tmp_df.txt|while read lv_name fs_type total_size used_size ava_size used_rate mounted
do
#echo " 卷名 类型 总大小M 使用大小M 可用大小M 使用率% 挂载点 "
if [ 90 -lt ${used_rate} ] && [ ${ava_size} -lt 1024 ];then
#echo "The System ${lv_name} mountd not space"
echo "${lv_name} ${fs_type} ${total_size} ${used_size} ${used_rate} ${mounted}" >> second_tmp_df.txt
else
echo "`date` The System all mounted space free ok !!!!" >> /var/log/message
fi
done
}

#判断选择的挂载点是否满足自动扩容的先决条件,是逻辑卷还是标准分区
Condition_check(){

tmp_notice_Standard.txt
row_num=`cat second_tmp_df.txt|wc -l`
if [ $row_num -eq 0 ];then
echo "`date` All Enough space for all partitions ,Status ok !!!" >> /var/log/message
else
cat second_tmp_df.txt|while read lv_name fs_type total_size used_size used_rate mounted
do
#标准分区的最后有PARTUUID字段,判断是否能够取出PARTUUID来区分。
blkid ${lv_name} | grep -i PARTUUID &>/dev/null
if [ $? -eq 0 ];then
echo "`date` ${lv_name} is standard partition Standard partitions do not automatically expand." >> tmp_notice_Standard.txt
echo "`date` The ${lv_name} insufficient disk space,standard partition Standard partitions do not automatically expand." >> /var/log/message
else
#echo -e "\n-------------------------------------------\n1.The partition format check passed.\nThe ${lv_name} not standard partition.\n"
add_lv_space ${lv_name} ${fs_type} ${mounted}
fi
done
fi
}

#需要获取两个值 一个是挂载点路径 一个是挂载格式
#暂时不用判断直接扩容,每次扩2G。可根据自己实际环境调节
add_lv_space(){
#通过传参获取到逻辑磁盘信息
lv_name_tmp=${1:-notvalues}
lv_type_tmp=${2:-notvalues}
lv_mount_tmp=${3:-notvalues}

lvextend -L +2G ${lv_name_tmp} &> /dev/null
if [ $? -eq 0 ];then
echo "`date` ${lv_name_tmp} exec lvextend command Space expansion success." >> /var/log/message
if [ "${lv_type_tmp}" == "ext3" ] || [ "${lv_type_tmp}" == "ext2" ] || [ "${lv_type_tmp}" == "ext4" ];then
#ext2 ext3 ext4 格式刷新大小
resize2fs ${lv_name_tmp} &> /dev/null
if [ $? -eq 0 ];then
echo "`date` ${lv_name_tmp} resize success." >> /var/log/message
else
echo "`date` ${lv_name_tmp} resize failed." >> /var/log/message
fi
elif [ "${lv_type_tmp}" == "xfs" ];then
#xfs 格式刷新大小
xfs_growfs ${lv_mount_tmp} &> /dev/null
if [ $? -eq 0 ];then
echo "`date` ${lv_name_tmp} resize success." >> /var/log/message
else
echo "`date` ${lv_name_tmp} resize failed." >> /var/log/message
fi
fi
else
echo "`date` ${lv_name_tmp} exec lvextend command Space expansion failed." >> /var/log/message
exit 66
fi

}

#清除临时文件
clear_tmp_file(){
rm -rf tmp_df.txt
rm -rf second_tmp_df.txt
rm -rf tmp_notice_Standard.txt
}

#如果扩容不成功包括 为标准分区、没有空余磁盘等情况发送邮件操作
Send_mail(){
notici_num=`cat tmp_notice_Standard.txt|wc -l`
if [ ${notici_num:-0} -gt 0 ];then
echo "`cat tmp_notice_Standard.txt`" | mail -s "标准分区需扩容" XXXXXXXX@163.com XXXXXXXXX@qq.com
else
#没有需要扩容的标准分区磁盘
sleep 1
fi
}

#主函数
main(){
Scan_new_disk
System_check_space
Condition_check
Send_mail
clear_tmp_file
}

#调用主函数
main

结果

日志结果

邮件结果

**************************************************************************************************************2021年2月8日脚本结束*****************************************************************************************************************

************************************************************************************************************************************************************************************************************************************

脚本说明

检测系统中指定的文件,通过保存的md5对比当前文件的md5对比是否更改,如果md5不一样则判断文件不一致内容输出到日志中。

在系统上线过后一般情况下没人会去动/etc/fstab和/etc/passwd,/etc/group这些静态文件。如果这些文件变化表示存在内容修改,可以检查一下是否属于合法修改。

文件说明

Check_file_md5_change.sh:脚本主体文件

脚本主体

[root@135 14_Check_file_md5]# cat Check_file_md5_change.sh
#!/bin/bash
Check_file_md5(){
#读取文件路径生成MD5保存到临时文件中
first_ctl=0
for file_name in /etc/passwd /etc/group /etc/shadow
do
if [ -f .history_sum.txt ];then
#如果first_ctl变量为1表示为第一次获取md5值
if [ ${first_ctl} -eq 1 ];then
md5sum $file_name >> .history_sum.txt
else
echo "不是第一次检测md5值"
fi

  #对比md5值  
  new\_sum=\`md5sum  $file\_name|awk '{printf $1}'\`  
  old\_sum=\`cat  .history\_sum.txt |grep  ${file\_name}|awk '{printf $1}'\`  
  if \[ "${new\_sum}" == "${old\_sum}" \];then  
    echo "\`date\` Check ${file\_name} not changed."   >> /var/log/message  
  else  
     echo "\`date\` Check ${file\_name}  changed!!!"   >> /var/log/message  
  fi      

else  
  #地没有历史文件,创建一个并且把控制变量置1  
  first\_ctl=1  
  md5sum  $file\_name >> .history\_sum.txt  
  echo "\`date\` Check ${file\_name} not changed."  >> /var/log/message  
fi  

done
}

main(){
Check_file_md5
}

main

结果

执行测试命令

日志结果

**************************************************************************************************************2021年2月9日脚本结束*****************************************************************************************************************

************************************************************************************************************************************************************************************************************************************

脚本说明

在操作系统安装完成后对操作系统进行一些简单设置,设置密码最大生命周期未90天,修改sshd中常用参数如不允许root用户使用ssh登录,为历史执行命令添加上时间戳,修改最大的历史日志记录数为5000条。

文件说明

Initial_System_Settings.sh :脚本主体文件

脚本主体

[root@135 15_Initial_System_Settings]# cat Initial_System_Settings.sh
#!/bin/bash

#设置密码过期时间,已存在的用户不生效。
Password_Life_Cycle(){
cp /etc/login.defs /etc/login.defs.bak
if [ -f /etc/login.defs.bak ];then
sed -i 's/PASS_MAX_DAYS.*/PASS_MAX_DAYS\ 90/' /etc/login.defs &>/dev/null
fi

cat /etc/login.defs | grep -i 'PASS_MAX_DAYS 90' &> /dev/null
if [ $? -eq 0 ];then
echo "设置密码过期时间为90天。"
else
echo "设置密码过期时间为90天失败。"
fi
}

#修改系统历史命令格式
history_info(){
cp -rp /etc/profile /etc/profile.bakk
cp -rp /etc/bashrc /etc/bashrc.bakk
if [ -f /etc/profile.bakk ] && [ -f /etc/bashrc.bakk ];then
sed -i 's/^HISTSIZE=.*/HISTSIZE=5000/' /etc/profile &>/dev/null
sed -i '/HISTTIMEFORMAT.*/d' /etc/profile &>/dev/null
sed -i '/HISTTIMEFORMAT.*/d' /etc/bashrc &>/dev/null
echo "export HISTTIMEFORMAT='%F %T'\" \" " >> /etc/bashrc
fi

if cat /etc/profile | grep -i HISTSIZE=5000 &>/dev/null && cat /etc/bashrc | grep -i 'HISTTIMEFORMAT=' &>/dev/null;then
echo "成功:最大历史记录数5000条,添加命令执行时间戳。"
else
echo "失败:修改记录历史命令格式。"
fi

}

#修改ssh参数加快运行
#配置root不能远程登录系统
edit_sshd(){
cp -rp /etc/ssh/sshd_config /etc/ssh/sshd_config.bakk
if [ -f /etc/ssh/sshd_config.bakk ];then
sed -i '/PermitRootLogin/d' /etc/ssh/sshd_config
echo 'PermitRootLogin no' >> /etc/ssh/sshd_config

sed -i '/UseDNS/d' /etc/ssh/sshd\_config  
echo 'UseDNS no' >> /etc/ssh/sshd\_config

sed -i '/GSSAPIAuthentication/d' /etc/ssh/sshd\_config  
sed -i '/GSSAPICleanupCredentials/d' /etc/ssh/sshd\_config  
echo 'GSSAPIAuthentication no' >> /etc/ssh/sshd\_config  
echo 'GSSAPICleanupCredentials no' >> /etc/ssh/sshd\_config

fi

if cat /etc/ssh/sshd_config | grep -Ei 'PermitRootLogin.*yes' &>/dev/null;then
echo "未设置不允许root登录。"
else
echo "已设置不允许root登录。"
fi

if cat /etc/ssh/sshd_config | grep -Ei 'UseDNS.*yes' &>/dev/null;then
echo "未设置UseDNS no。"
else
echo "已设置UseDNS no。"
fi

if cat /etc/ssh/sshd_config | grep -Ei 'GSSAPICleanupCredentials.*no' &>/dev/null && cat /etc/ssh/sshd_config | grep -Ei 'GSSAPIAuthentication.*no' &>/dev/null ;then
echo "设置成功不验证图形界面。"
else
echo "设置失败不验证图形界面。"
fi

if service sshd restart &>/dev/null || systemctl restart sshd &> /dev/null;then
echo "SSHD 远程服务重启完成。"
else
echo "SSHD 远程服务重启失败,请检查配置文件是否错误。"
fi

}

#是否警用selinux
Close_selinux(){
read -p "Close Selinx, Input yes(y) or No(n),Default not close。: " chose
decide=${chose:-n}
if [ "${decide}" == "y" ] || [ "${decide}" == "yes" ] || [ "${decide}" == "YES" ] ;then
setenforce 0 &> /dev/null
sed -i '/^SELINUX=/d' /etc/selinux/config
echo 'SELINUX=disabled' >> /etc/selinux/config
echo "已对selinux进行关闭。"
else
echo "未对selinux配置及状态进行修改。"
fi
}

#选择是否警用防火墙
Close_firewalld(){
read -p "关闭防火墙, 输入 yes(y) 或 No(n),默认不关闭。: " chosef
decide=${chosef:-n}
if [ "${decide}" == "y" ] || [ "${decide}" == "yes" ] || [ "${decide}" == "YES" ] ;then
service iptables stop &> /dev/null
chkconfig iptables off &> /dev/null
systemctl stop iptables &>/dev/null
systemctl stop nftables &>/dev/null
systemctl stop firewalld &>/dev/null
systemctl disable iptables &>/dev/null
systemctl disable nftables &>/dev/null
systemctl disable firewalld &>/dev/null
echo "已对防火墙软件进行停用操作。"
else
echo "未停用防火墙。"
fi

}

#定义主函数手动选择是否执行某一个函数
main(){
echo -e "\n…….. Start run System Initial program …….."
Password_Life_Cycle
history_info
edit_sshd
Close_selinux
Close_firewalld
echo -e "\n…….. System initialization is complete ……..\n\n"
}
main

结果

**************************************************************************************************************2021年2月10日脚本结束*****************************************************************************************************************