日常运维工作中可能会用到一些常用的脚本,本文通过整理常用的经典脚本,当需要使用时可以进行修改使用。
参考视屏地址:案例讲解
#!bin/bash
#背景:新购买10台服务器并已安装Linux操作
#需求:
#1)设置时区并同步时间
#2)禁用selinux
#3)清空防火墙默认策略
#4)历史命令显示操作时间
#5)禁止root远程登录
#6)禁止定时任务发送邮件
#7)设置最大打开文件数
#8)减少Swap使用
#9)系统内核参数优化
#10)安装系统性能分析工具及其他
#1)设置时区并同步时间
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
if ! crontab -l |grep ntpdata & >/dev/null;then
(echo "* 1 * * * ntpdata time.wiindows.com >/dev/null 2>&1";crontab -l) |crontab
fi
#2)禁用selinux
sed -i '/SELINUX/{s/permissive/disabled/}' /etc/selinux/config
#3)清空防火墙默认策略-关闭防火墙
if egrep "7.[0-9]" /etc/redhat-release &>/dev/null; then
systemctl stop firewalld
systemctl disable firewalld
elif egrep "6.[0-9]" /etc/redhat-rekease &>dev/null; then
service iptables stop
chkconfig iptables off
fi
#4)历史命令显示操作时间
if ! grep HISTTIMEFORMAT /etc/bashrc;then
echo 'export HISTTIMEFORMAT="%F %T `whoami`"' >> /etc/bashrc
fi
#ssh超时时间
if ! grep "TMOUT=600" /etc/profile &>/dev/null;then
echo "export TMOUT=600" >> /etc/profile
fi
#5)禁止root远程登录
sed -i 's/#permitRootLogin yes/permitRootLogin no/' /etc/ssh/sshd_config
#6)禁止定时任务发送邮件
sed -i 's/^MAILTO=root/MAILTO=""/' /etc/crontab
#7)设置最大打开文件数
if ! grep "* soft nofile 65535" /etc/security/limits.conf &>/dev/null;then
cat >> /etc/security/limits.conf <<EOF
* soft nofile 65535
* hard nofile 65535
EOF
fi
#8)减少Swap使用
echo "0" > /proc/sys/vm/swappiness
#9)系统内核参数优化
cat >> /etc/sysctl.conf <<EOF
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_tw_buckets = 20480
net.ipv4.tcp_max_syn_backlog = 20480
net.core.netdev_max_backlog = 262144
net,ipv4,tcp_fin_timeout = 20
EOF
#10)安装系统性能分析工具及其他
yum install gcc make autoconf vim sysstat net-toos iostat iftop iotp lrzsz -y
#!/bin/bash
#安装邮箱服务器
yum install mailx -y
#配置邮箱
vim /etc/mail.rc
# 配置发件邮箱信息
set from=1294397385@qq.com #发件邮箱
set smtp=smtp.qq.com
set smtp-auth-user=1294397385@qq.com #发件邮箱
set smtp-auth-password=itiwaejzatspqhaij #配置授权码
set smtp-auth=login
#发油测试
echo "hello,小白,这是一个基于centos7系统配置的邮件发送端,用于服务器告警信息的通知,现在正在测试邮箱发送的可靠,性"|mail -s "邮箱发送的测试" 1294397385@qq.com
#!/bin/bash
USER_LIST=$@
USER_FILE=./user.info
for USER in $USER_LIST;do
if ! id $USER &>/dev/null;then
PASS=$(echo $RANDOM |md5sum |cut -c 1-8)
useradd $USER
echo $PASS | passwd --stdin $USER &>/dev/null
echo "$USER" "$PASS" >> $USER_FILE
echo "$USER User create successful"
else
echo "$USER User already exists!"
fi
done
#!/bin/bash
#1) CPU 60%
#2) 内存 利用率
#3)硬盘 利用率
#4) TCP 链接状态
#1) CPU 60%
function cpu(){
util=$(vmstat |awk '{if(NR==3)print $13+$14}')
iowait=$(vmstat |awk '{if(NR==3)print $16}')
echo "CPU使用率:${uti}%, 等待磁盘IO响应使用率: ${ioawit}%"
}
#2) 内存 利用率
function memory(){
total=$(free -m |awk '{if(NR==2)printf "%.1f",$2/1024}')
used=$(free -m |awk '{if(NR==2)printf "%.1f",($2-$NF)/1024}')
available=$(free -m |awk '{if(NR==2)printf "%.1f",$NF/1024}')
echo "内存-总大小:${total}G,已使用:${used}G,可用:${available}G "
}
#3)硬盘 利用率
function disk(){
fs=$(df -h |awk '/^\/dev/{print $1}')
for p in $fs; do
mounted=$(df -h |awk -v p=$p '$1==p{print $NF}')
size=$(df -h |awk -v p=$p '$1==p{print $2}')
used=$(df -h |awk -v p=$p '$1==p{print $3}')
used_percent=$(df -h |awk -v p=$p '$1==p{print $5}')
echo "硬盘-挂载点:${mounted},总大小:${size},已使用:${used},使用率:${used_percent}"
done
}
#4) TCP 链接状态
function tcp_status(){
summary=$(netstat -antp |awk '{a[$6]++}END{for(i in a)printf i":"a[i]" "}')
echo "tcp链接状态- ${summary}"
}
cpu
memory
disk
tcp_status
~
#!/bin/bash
#cputop
echo "---------cpu top 10-------------------"
ps -eo pid,pcpu,pmem,args --sort=-pcpu |head -n 10
#内存top
echo "---------memory top 10-------------------"
ps -eo pid,pcpu,pmem,args --sort=-pmem |head -n 10
使用时注意传入参数$1
#!/bin/bash
NIC=$1
echo -e "In ------ Out"
while true; do
OLD_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)
OLD_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)
sleep 1
NEW_IN=$(awk '$0~"'$NIC'"{print $2}' /proc/net/dev)
NEW_OUT=$(awk '$0~"'$NIC'"{print $10}' /proc/net/dev)
IN=$(printf "%.1f%s" "$((($NEW_IN-$OLD_IN)/1024))" "KB/s")
OUT=$(printf "%.1f%s" "$((($NEW_OUT-$OLD_OUT)/1024))" "KB/s")
echo "$IN $OUT"
sleep 1
done
#免密配置
#(1)在主服务器上生成密钥对
#(2)在主服务器上/etc/hosts 配置上免密服务器的主机名与ip地址
#(3)将公钥发给需要免密的服务器
#(4)配置完成后可以使用 “ssh root@ip” 或 “ssh ip” 或 “ssh 主机名” 直接登录免密服务器
#(1)在主服务器上生成密钥对
[root@mysql-master ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:mQlqMmc4YfHu8Mp30UTs892MCwrZNk4+tF4kCitT0SU root@mysql-master
The key's randomart image is:
+---[RSA 2048]----+
| . E.. |
| o . oo |
| o o oo |
| . + o .++ |
| * O =So.. + |
| % o+.Boo o o |
| o + .O +.. . |
| . +. . *. . |
| o. . ... |
+----[SHA256]-----+
#(2)在主服务器上/etc/hosts 配置上免密服务器的主机名与ip地址
[root@mysql-master ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.10.51 mysql-node1
#(3)将公钥发给需要免密的服务器
[root@mysql-master ~]# ssh-copy-id [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.10.51 (192.168.10.51)' can't be established.
ECDSA key fingerprint is SHA256:Jzzsc0Qp45ZKRx6IQjhJVvx6ZQ/5sctyI+TeUR6snmE.
ECDSA key fingerprint is MD5:18:41:0b:6a:d3:14:7a:a7:da:a0:f0:9a:33:79:d9:c6.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
#(4)配置完成后可以使用 “ssh root@ip” 或 “ssh ip” 或 “ssh 主机名” 直接登录免密服务器
[root@mysql-master ~]# ssh '[email protected]'
Last login: Tue Jul 18 06:06:24 2023 from 192.168.10.1
[root@mysql-node1 ~]# exit
logout
Connection to 192.168.10.51 closed.
[root@mysql-master ~]# ssh [email protected]
Last login: Thu Jul 20 01:53:44 2023 from 192.168.10.50
[root@mysql-node1 ~]# exit
logout
Connection to 192.168.10.51 closed.
[root@mysql-master ~]# ssh 192.168.10.51
Last login: Thu Jul 20 01:54:10 2023 from 192.168.10.50
[root@mysql-node1 ~]# exit
#!/bin/bash
HOST_INFO=host.info
for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
TMP_FILE=/tmp/disk.tmp
ssh -p $PORT $USER@$IP 'df -h' > $TMP_FILE
USE_RATE_LIST=$(awk 'BEGIN{OFS="="}/^\/dev/{print $NF,int($5)}' $TMP_FILE)
#循环获取到挂载目录和磁盘使用情况信息,满足设定的条件即输出结果
for USE_RATE in $USE_RATE_LIST; do
#${USE_RATE%=*}表示取等号左边值
PART_NAME=${USE_RATE%=*}
#${USE_RATE#*=}表示取等号右边值
USE_RATE=${USE_RATE#*=}
if [ $USE_RATE -ge 15 ]; then
#-e指定换行 \n是换行符
echo -e "$IP \n Warning: $PART_NAME Partition usage $USE_RATE%!"
else
#-e指定换行 \n是换行符
echo -e "$IP \n YES,在阀值内!!"
fi
done
done
#!/bin/bash
URL_LIST="www.baidu.com www.ctnrs.com"
for URL in $URL_LIST; do
FAIL_COUNT=0
for ((i=1;i<=3;i++));do
HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $URL)
if [ $HTTP_CODE -eq 200 ]; then
echo "$URL OK"
break
else
echo "retry $FAIL_COUNT"
let FAIL_COUNT++
fi
done
if [ $FAIL_COUNT -eq 3 ]; then
echo "warning: $URL Access failure!"
fi
done
vim host_info
192.168.10.51 root 22
192.168.10.52 root 22
#!/bin/bash
HOST_INFO=host.info
for IP in $(awk '/^[^#]/{print $1}' $HOST_INFO); do
USER=$(awk -v ip=$IP 'ip==$1{print $2}' $HOST_INFO)
PORT=$(awk -v ip=$IP 'ip==$1{print $3}' $HOST_INFO)
PASS=$(awk -v ip=$IP 'ip==$1{print $4}' $HOST_INFO)
expect -c "
spawn ssh -p $PORT $USER@$IP
expect {
\"(yes/no)\" {send \"yes\r\"; exp_continue}
\"password:\" {send \"$PASS\r\"; exp_continue}
\"$USER@*\"{send \"$COMMAND\r exit\r\"; exp_continue}
}
"
echo "--------------------"
done
#!/bin/bash
NGINX_V=1.15.6
PHP_V=5.6.36
TMP_DIR=/tmp
INSTALL_DIR=/usr/local
PWD_C=$PWD
echo
echo -e "\tMenu\n"
echo -e "1. Install Nginx"
echo -e "2. Install PHP"
echo -e "3. Install MySQL"
echo -e "4. Install LNMP"
echo -e "9. Quit"
function commnd_status_check(){
if [ $? -ne 0 ];then
echo $1
exit 1
fi
}
function install_nginx(){
cd $TMP_DIR
yum install-y gcc gcc-c++ make openssl-devel pcre-devel wget
wget http://nginx.org/download/nginx-$[NGINX V}.tar.gz
tar zxf nginx-$[NGINX_V}.tar.gz
cd nginx-${NGINX V}
-/configure --prefix=$INSTALL DIR/nginx
--with-http ssl module
--with-http stub status module
--with-stream
平台环境检查失败!command status check “Nginxmake -i4- 编译失败!
make -j 4
“command status_check “Nginx- 编译失败!“
make install
command status check "Nginx安装失败!
mkdir -p $INSTALL DIR/nginx/conf/vhost
alias cp=cp;cp -rf $PWD C/nginx.conf $INSTALL DIR/nginx/conf
rm -rf $INSTALL DIR/nginx/html/*
}
function install_php(){
Cd $TMP DIR
yum-install -y gcc gec-c++ make gd-devel libxml2-devellibcurl-devel libjpeg-devel libpng-devel openssl-devellibmcrypt-devel libxslt-devel libtidy-devel
wget http://docs.php.net/distributions/php-${PHP_V}.tar.gz
tar zxf php-${PHP V}.tar.gz
cd php-$fPHP V}
./configure --prefix=$INSTALL DIR/php-with-config-file-path=$INSTALL DIR/php/etc-enable-fpm
--enable-opcache--with-mysql--with-mysqli
--with-pdo-mysgl--with-openssl --with-zlib
--with-curl --with-gd--with-jpeg-dir
--with-png-dir --with-freetype-dir-enable-mbstring
--enable-hash
command status check “PHP -平台环境检查失败!“
make-j4
command status check “PHP编译失败!
make install
command status check “PHP - 安装失败!“
Cpphp.ini-production $INSTALL DIR/php/etc/php.inisapi/fpm/php-fpm.conf $INSTALL DIR/php/etc/php-fpm.conf
Cpcp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpmchmod +x /etc/init.d/php-fpm/etc/init.d/ status check “PHP
php-fpm start- 启动失败!“
}
read -p "请输入编号:" number
case $number in
1)
install_nginx;;
2)
install_php;;
3)
install_mysql;;
4)
insatll_nginx
install_php
;;
9)
exit;;
esac
#!/bin/bash
change master to
master_host='192.168.10.130',
master_user='rep1',
master_password='password',
master_log_file='mysql-bin.000005',
master_log_pos=261;
# 主从同步
# master binlog
# slave
写 -》 master ->binlog <-relaylog -slave 读
mysql -uroot -p123.com -e "show slave status\G;" |awk '{print $}'
#!/bin/bash
HOST=localhost
USER=root
PASSWD=123.comIO SQL STATUS=$(mysgl -h$HOST -USUSER -pSPASSWD -e 'show slave statusiG'2>/dev/null awk/Slave .* Running:/{print $1$2]')for i in $IO SQL STATUS; doTHREAD STATUS NAME=$ i%:*]THREAD STATUS=${i#*:}if["STHREAD STATUS” != "Yes"]; thenecho "Error: MySQL MasterSlave $THREAD STATUS NAME status is $THREAD STATUS!"fi
done
#!/bin/bash
HOST=localhost
USER=root
PASSWD=123.com
IO_SQL_STATUS=$(mysgl -h$HOST -U$USER -p$PASSWD -e 'show slave statusiG' 2>/dev/null |awk '/Slave .*_Running:/{print $1$2]')
for i in $IO_SQL_STATUS; do
THREAD_STATUS_NAME=${i%:*}
THREAD_STATUS=${i#*:}
if [ "STHREAD_STATUS” != "Yes" ]; then
echo "Error: MySQL-MasterSlave $THREAD_STATUS_NAME status is $THREAD_TATUS!"fi
done
#备份数据库
#!/bin/bash
DATA=$(data +%F_%H_%M_%S)
HOST=localhost
UTSER=backup
PASS=123.com
BACKUPDIR=/data/db backup
DB_LISF=$(mysql -h$HOST -U$SUSER -P$PASS s -e "show databases;" 2>/dev/null |egrep -v "Dat-abase|information_ schema|mysgl|performance_schema|sys")
for DB in $DB LIST; do
BACKUP_NAME=SBACKUP_DIR/${DB}_${DATE}.Sql
if ! mysqldump -h$HOST -u$USER -p$PASS -B $DB > $BACKUP_NAME 2>/dev/null; then
echo“$BACKUP_NAME 备份失败!"
done
#数据库表备份
#!/bin/bash
DATA=$(data +%F_%H_%M_%S)
HOST=localhost
UTSER=backup
PASS=123.com
BACKUPDIR=/data/db backup
DB_LISF=$(mysql -h$HOST -U$SUSER -P$PASS s -e "show databases;" 2>/dev/null |egrep -v "Dat-abase|information_ schema|mysgl|performance_schema|sys")
for DB in $DB LIST; do
BACKUP_NAME=SBACKUP_DIR/${DB}_${DATE}.Sql
[ ! -d $BACKUP_DB_DIR ] && mkdir -p $BACKUP_DB_DIR &>/dev/null
TABLE_LIST=$(mysql -h$HOST -u$USER -P$PASS -s -e "use $DB;show tables;" 2>/dev/null)
for TABLE IN $TABLE_LIST; do
BACKUP_NAME=$BACKUP_DB_DIR/${TABLE}.Sql
if ! mysqldump -h$HOST -u$USER -p$PASS $DB $TABLE > $BACKUP_NAME 2>/dev/null; then
echo“$BACKUP_NAME 备份失败!"
fi
done
done
#!/bain/bash
#1.访问最多的IP
#2.访问最多的页面
#3.访问状态码数量
#4.根据时间段来获取访问最多的IP
LOG_FILE=$1
echo "统计访问最多的ip"
awk '{a[$1]++}END{print "UV:",length(a);for(v in a)print v,a[v]}' $LOG_FILE |sort -k2 -nr |head -10
echo "-------------------"
echo "统计时间段访问最多的IP"
awk '$4>="[21/Jul/2023:20:40:22" && $4<="[21/Jul/2023:20:41:39" {a[$1]++}END{for(v in a)print a[v],v}' $LOG_FILE |sort -k2 -nr|head -10
echo "-------------------"
echo "统计访问最多的10个页面"
awk '{a[$7]++}END{print "PV:",length(a);for(v in a){if(a[v]>10)print v,a[v]}}' $LOG_FILE |sort -k2 -nr
echo "-------------------"
echo "统计访问页面状态码数量"
awk '{a[$7" "$9]++}END{for(v in a){if(a[v]>5)print v,a[v]}}' $LOG_FILE |sort -k3 -nr
#!/bin/bash
L0G_DIR=/usr/local/nginx/logs
YESTERDAY_TIME=$(date -d“yesterday" +%F
L0G_MONTH_DIR=$LOG_DIR/$(date +"%Y-%m")
L0G_FILE_LIST="access.log"
for LOG_FILE in $LOG_FILE_LIST; do
[ ! -d $LOG_MONTH_DIR ] && mkdir -p $LOG_MONTH_DIR
mv $LOG_DIR/$LOG_FILE $LOG_MONTH_DIR/${LOG_FILE}_${YESTERDAY_TIME}
done
kill -USR1 $(cat /var/run/nginx.pid)
#!/bin/bash
#代码已经到版本仓库,执行shell脚本一键部署
#!/bin/bash
DATE=$(date +%F_%T)
TOMCAT_NAME=$1
TOMCA1_DIR=/usr/local/$TOMCAT_NAME
R00T=${TOMCAT_DIR}/webapps/R00T
BACKUP_DIR=/data/backup
WORK_DIR=/tmp
PROJECT_NAME=tomcat-java-demo
#拉取代码与构建
cd $WORK_DIR
if [ ! -d $PROJECT_NAME ];then
git clone https://github.com/lizhenliang/tomcat-java-demo
cd $PROJECT_NAME
else
cd SPROJECT_NAME
git pull
fi
#构建
mvn clean package -Dmaven.test.skip=true
if [ $? -ne 0 ]; then
echo "maven build failure!"
exit 1
fi
# 部署
TOMTAT_PID=$(ps -ef |grep "$TOMCAT_NAME" |egrep -v "grep|$$" |awk 'NR==1{print $2}')
[ -n "TOMCAT_PID" ] && kill -9 $TOMCAT_PID
[ -d $ROOT ] && mv $ROOT $BACKUP_DIR/${TOMCAT_NAME}_ROOT$DATE
unzip $WORK DIR/$PROJECT_NAME/target/*.war -d $ROOT
$TOMCAT_DIR/bin/startup.sh
#!/bin/bash
#拉取代码
#同步代码 rsync
BACKUP_DIR=/data/backup
WORK_DIR=/tmp
PROJECT_NAME=php-demo
#拉取代码
cd $WORK_DIR
if [ ! -d $PROJECT_NAME ]; then
git clone https://github.com/lizhenliang/php-demo
cd $PROJECT_NAME
else
cd $PROJECT_NAME
git pull
fi
# 部署
if [ ! d $WWWROOT ];then
mkdir -p $WWWROOT
else
rsync -avz --exclude=.git $WORK_DIR/$PROJECT_NAME $WWWROOT
fi
#!/bin/bash
DATA=$(date +%d/%b/%Y:%H:%M)
LOG_FILE=/usr/local/nginx/logs/demo.access.log
ABNORMAL_IP=$(tail -n 5000 $LOG_FILE |grep $DATE |awk '{a[$1]++}END{for(i in a)if(a[i]>100)print i}')
for IP in $ABNORMAL_IP;do
if [ $(iptables -vnL |grep -c "$IP") -eq 0 ]; then
iptables -I INPUT -s $IP -j DROP
echo "$(date +'%F_%T') $IP" >> /tmp/drop_ip.log
fi
done
~
inotify可以对linux 文件系统进行高效性、细粒度、异步的监控,用于通知用户控件程序的文件系统变化。inotify可以监控文件,也可以监控目录,配合rsync实现文件的实时同步功能。
首先安装inotify软件,先检查自己的系统版本(uname -r),我的是centos 7的系统,我的步骤是
1、首先检查自己的电脑是否已经安装了这个软件。 rpm -qa inotify-tools
2、检查仓库中是否有这个软件。 yum search inotify-tools
3、发现这个软件不在yum仓库中,安装对应的epel源。
wget -O /etc/yum.repos.d/epel-7.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all
yum makecache
4、安装inotify-tools软件
yum install -y inotify-tools
#!/bin/bash
MON_DIR=/opt
inotifywait -mqr --format %f -e create $MON_DIR |\
while read files;do
rsync -avz /opt /tmp/opt
# 这可以配置邮件通知信息
echo "$(date+'%F %T') $files" >> file_mon.log
done
19.检测ssl证书剩余时间
#!/bin/bash
server_name=$1
#获取网站的证书有效期
#获取ssl过期时间的命令
#1.获取有效期的日志
ssl_time=$(echo | openssl s_client -servername ${server_name} -connect ${server_name}:443 2>/dev/null | openssl x509 -noout -dates|awk -F '=' '/notAfter/{print $2}')
#2.转换时间戳
#把日志转变为时间戳,时间戳就可以去计算了
#转为unix日期格式,然后可以对日期进行计算
ssl_unix_time=$(date +%s -d "${ssl_time}")
#获取今天时间戳
today=$(date +%s)
#计算剩余时间
#利用let命令去数学运算从到期时间,减去今天的日期,然后单位换算,看看过期还有多久
#最终将时间戳,转为天的单位
let expr_time=(${ssl_unix_time}-${today})/24/3600
echo "${server_name} 该ssl证书剩余时间:${expr_time} 天"