Comprehensive Linux Daily Inspection Script for System Health Monitoring
This article presents a Bash script that performs a full daily health check on a Linux server—covering disk usage, memory, CPU, processes, file changes, user logins, network settings, services, cron jobs, and security configurations—and then emails the generated report.
Linux系统日常巡检脚本,检查内容包括磁盘、内存、CPU、进程、文件更改、用户登录等一系列操作,直接使用即可,报告通过邮件发送并保存在log目录下。
#!/bin/bash
# @Author: HanWei
# @Date: 2020-03-16 09:56:57
# @Last Modified by: HanWei
# @Last Modified time: 2020-03-16 11:06:31
# @E-mail: [email protected]
#!/bin/bash
#主机信息每日巡检
IPADDR=$(ifconfig eth0|grep 'inet addr'|awk -F '[ :]' '{print $13}')
export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
source /etc/profile
[ $(id -u) -gt 0 ] && echo "请用root用户执行此脚本!" && exit 1
centosVersion=$(awk '{print $(NF-1)}' /etc/redhat-release)
VERSION="2020-03-16"
#日志相关
PROGPATH=`echo $0 | sed -e 's,[\/][^\/][^\/]*$,,'`
[ -f $PROGPATH ] && PROGPATH="."
LOGPATH="$PROGPATH/log"
[ -e $LOGPATH ] || mkdir $LOGPATH
RESULTFILE="$LOGPATH/HostDailyCheck-$IPADDR-$(date +%Y%m%d).txt"
#定义报表的全局变量
report_DateTime=""
report_Hostname=""
report_OSRelease=""
report_Kernel=""
report_Language=""
report_LastReboot=""
report_Uptime=""
report_CPUs=""
report_CPUType=""
report_Arch=""
report_MemTotal=""
report_MemFree=""
report_MemUsedPercent=""
report_DiskTotal=""
report_DiskFree=""
report_DiskUsedPercent=""
report_InodeTotal=""
report_InodeFree=""
report_InodeUsedPercent=""
report_IP=""
report_MAC=""
report_Gateway=""
report_DNS=""
report_Listen=""
report_Selinux=""
report_Firewall=""
report_USERs=""
report_USEREmptyPassword=""
report_USERTheSameUID=""
report_PasswordExpiry=""
report_RootUser=""
report_Sudoers=""
report_SSHAuthorized=""
report_SSHDProtocolVersion=""
report_SSHDPermitRootLogin=""
report_DefunctProsess=""
report_SelfInitiatedService=""
report_SelfInitiatedProgram=""
report_RuningService=""
report_Crontab=""
report_Syslog=""
report_SNMP=""
report_NTP=""
report_JDK=""
function version(){
echo ""
echo ""
echo "系统巡检脚本:Version $VERSION"
}
function getCpuStatus(){
echo ""
echo ""
echo "############################ CPU检查 #############################"
Physical_CPUs=$(grep "physical id" /proc/cpuinfo| sort | uniq | wc -l)
Virt_CPUs=$(grep "processor" /proc/cpuinfo | wc -l)
CPU_Kernels=$(grep "cores" /proc/cpuinfo|uniq| awk -F ': ' '{print $2}')
CPU_Type=$(grep "model name" /proc/cpuinfo | awk -F ': ' '{print $2}' | sort | uniq)
CPU_Arch=$(uname -m)
echo "物理CPU个数:$Physical_CPUs"
echo "逻辑CPU个数:$Virt_CPUs"
echo "每CPU核心数:$CPU_Kernels"
echo " CPU型号:$CPU_Type"
echo " CPU架构:$CPU_Arch"
report_CPUs=$Virt_CPUs
report_CPUType=$CPU_Type
report_Arch=$CPU_Arch
}
function getMemStatus(){
echo ""
echo ""
echo "############################ 内存检查 ############################"
if [[ $centosVersion < 7 ]]; then
free -mo
else
free -h
fi
MemTotal=$(grep MemTotal /proc/meminfo| awk '{print $2}')
MemFree=$(grep MemFree /proc/meminfo| awk '{print $2}')
let MemUsed=MemTotal-MemFree
MemPercent=$(awk "BEGIN {if($MemTotal==0){printf 100}else{printf \"%.2f\",$MemUsed*100/$MemTotal}}")
report_MemTotal="$((MemTotal/1024))MB"
report_MemFree="$((MemFree/1024))MB"
report_MemUsedPercent="$MemPercent%"
}
function getDiskStatus(){
echo ""
echo ""
echo "############################ 磁盘检查 ############################"
df -hiP | sed 's/Mounted on/Mounted/' > /tmp/inode
df -hTP | sed 's/Mounted on/Mounted/' > /tmp/disk
join /tmp/disk /tmp/inode | awk '{print $1,$2,"|",$3,$4,$5,$6,"|",$8,$9,$10,$11,"|",$12}' | column -t
diskdata=$(df -TP | sed '1d' | awk '$2!="tmpfs"{print}')
disktotal=$(echo "$diskdata" | awk '{total+=$3}END{print total}')
diskused=$(echo "$diskdata" | awk '{total+=$4}END{print total}')
diskfree=$((disktotal-diskused))
diskusedpercent=$(echo $disktotal $diskused | awk '{if($1==0){printf 100}else{printf "%.2f",$2*100/$1}}')
inodedata=$(df -iTP | sed '1d' | awk '$2!="tmpfs"{print}')
inodetotal=$(echo "$inodedata" | awk '{total+=$3}END{print total}')
inodeused=$(echo "$inodedata" | awk '{total+=$4}END{print total}')
inodefree=$((inodetotal-inodeused))
inodeusedpercent=$(echo $inodetotal $inodeused | awk '{if($1==0){printf 100}else{printf "%.2f",$2*100/$1}}')
report_DiskTotal=$((disktotal/1024/1024))GB
report_DiskFree=$((diskfree/1024/1024))GB
report_DiskUsedPercent="$diskusedpercent%"
report_InodeTotal=$((inodetotal/1000))K
report_InodeFree=$((inodefree/1000))K
report_InodeUsedPercent="$inodeusedpercent%"
}
function getSystemStatus(){
echo ""
echo ""
echo "############################ 系统检查 ############################"
if [ -e /etc/sysconfig/i18n ]; then
default_LANG="$(grep LANG= /etc/sysconfig/i18n | grep -v '^#' | awk -F '"' '{print $2}')"
else
default_LANG=$LANG
fi
export LANG="en_US.UTF-8"
Release=$(cat /etc/redhat-release 2>/dev/null)
Kernel=$(uname -r)
OS=$(uname -o)
Hostname=$(uname -n)
SELinux=$(/usr/sbin/sestatus | grep "SELinux status:" | awk '{print $3}')
LastReboot=$(who -b | awk '{print $3,$4}')
uptime=$(uptime | sed 's/.*up \([^,]*\), .*/\1/')
echo " 系统:$OS"
echo " 发行版本:$Release"
echo " 内核:$Kernel"
echo " 主机名:$Hostname"
echo " SELinux:$SELinux"
echo "语言/编码:$default_LANG"
echo " 当前时间:$(date +'%F %T')"
echo " 最后启动:$LastReboot"
echo " 运行时间:$uptime"
report_DateTime=$(date +"%F %T")
report_Hostname="$Hostname"
report_OSRelease="$Release"
report_Kernel="$Kernel"
report_Language="$default_LANG"
report_LastReboot="$LastReboot"
report_Uptime="$uptime"
report_Selinux="$SELinux"
export LANG=$default_LANG
}
function getServiceStatus(){
echo ""
echo ""
echo "############################ 服务检查 ############################"
if [[ $centosVersion > 7 ]]; then
conf=$(systemctl list-unit-files --type=service --state=enabled --no-pager | grep "enabled")
process=$(systemctl list-units --type=service --state=running --no-pager | grep ".service")
report_SelfInitiatedService="$(echo "$conf" | wc -l)"
report_RuningService="$(echo "$process" | wc -l)"
else
conf=$(/sbin/chkconfig | grep -E ":on|:启用")
process=$(/sbin/service --status-all 2>/dev/null | grep -E "is running|正在运行")
report_SelfInitiatedService="$(echo "$conf" | wc -l)"
report_RuningService="$(echo "$process" | wc -l)"
fi
echo "服务配置"
echo "--------"
echo "$conf" | column -t
echo ""
echo "正在运行的服务"
echo "--------------"
echo "$process"
}
function getAutoStartStatus(){
echo ""
echo ""
echo "############################ 自启动检查 ##########################"
conf=$(grep -v "^#" /etc/rc.d/rc.local | sed '/^$/d')
echo "$conf"
report_SelfInitiatedProgram="$(echo $conf | wc -l)"
}
function getLoginStatus(){
echo ""
echo ""
echo "############################ 登录检查 ############################"
last | head
}
function getNetworkStatus(){
echo ""
echo ""
echo "############################ 网络检查 ############################"
if [[ $centosVersion < 7 ]]; then
/sbin/ifconfig -a | grep -v packets | grep -v collisions | grep -v inet6
else
for i in $(ip link | grep BROADCAST | awk -F: '{print $2}'); do
ip add show $i | grep -E "BROADCAST|global" | awk '{print $2}' | tr '
' ' '
echo ""
done
fi
GATEWAY=$(ip route | grep default | awk '{print $3}')
DNS=$(grep nameserver /etc/resolv.conf | grep -v "#" | awk '{print $2}' | tr '
' ',' | sed 's/,$//')
echo "网关:$GATEWAY "
echo " DNS:$DNS"
IP=$(ip -f inet addr | grep -v 127.0.0.1 | grep inet | awk '{print $NF,$2}' | tr '
' ',' | sed 's/,$//')
MAC=$(ip link | grep -v "LOOPBACK\|loopback" | awk '{print $2}' | tr -d '
' | tr '
' ',' | sed 's/,$//')
report_IP="$IP"
report_MAC=$MAC
report_Gateway="$GATEWAY"
report_DNS="$DNS"
}
function getListenStatus(){
echo ""
echo ""
echo "############################ 监听检查 ############################"
TCPListen=$(ss -ntul | column -t)
echo "$TCPListen"
report_Listen="$(echo "$TCPListen" | sed '1d' | awk '/tcp/ {print $5}' | awk -F: '{print $NF}' | sort | uniq | wc -l)"
}
function getCronStatus(){
echo ""
echo ""
echo "############################ 计划任务检查 ########################"
Crontab=0
for shell in $(grep -v "/sbin/nologin" /etc/shells); do
for user in $(grep "$shell" /etc/passwd | awk -F: '{print $1}'); do
crontab -l -u $user >/dev/null 2>&1
status=$?
if [ $status -eq 0 ]; then
echo "$user"
echo "--------"
crontab -l -u $user
let Crontab=Crontab+$(crontab -l -u $user | wc -l)
echo ""
fi
done
done
find /etc/cron* -type f | xargs -i ls -l {} | column -t
let Crontab=Crontab+$(find /etc/cron* -type f | wc -l)
report_Crontab="$Crontab"
}
function getUserStatus(){
echo ""
echo ""
echo "############################ 用户检查 ############################"
pwdfile="$(cat /etc/passwd)"
Modify=$(stat /etc/passwd | grep Modify | tr '.' ' ' | awk '{print $2,$3}')
echo "/etc/passwd 最后修改时间:$Modify ($(getHowLongAgo $Modify))"
echo ""
echo "特权用户"
echo "--------"
RootUser=""
for user in $(echo "$pwdfile" | awk -F: '{print $1}'); do
if [ $(id -u $user) -eq 0 ]; then
echo "$user"
RootUser=",$user"
fi
done
RootUser=$(echo $RootUser | sed 's/^,//')
echo ""
echo "用户列表"
echo "--------"
USERs=0
echo "$(
echo "用户名 UID GID HOME SHELL 最后一次登录"
for shell in $(grep -v "/sbin/nologin" /etc/shells); do
for username in $(grep "$shell" /etc/passwd | awk -F: '{print $1}'); do
userLastLogin="$(getUserLastLogin $username)"
echo "$pwdfile" | grep -w "$username" | grep -w "$shell" | awk -F: -v lastlogin="${userLastLogin// /_}" '{print $1,$3,$4,$6,$7,lastlogin}'
done
let USERs=USERs+$(echo "$pwdfile" | grep "$shell" | wc -l)
done
)" | column -t)
echo ""
echo "空密码用户"
echo "----------"
USEREmptyPassword=""
for shell in $(grep -v "/sbin/nologin" /etc/shells); do
for user in $(echo "$pwdfile" | grep "$shell" | cut -d: -f1); do
r=$(awk -F: '$2=="!!"{print $1}' /etc/shadow | grep -w $user)
if [ ! -z $r ]; then
echo $r
USEREmptyPassword="$USEREmptyPassword,$r"
fi
done
done
USEREmptyPassword=$(echo $USEREmptyPassword | sed 's/^,//')
echo ""
echo "相同ID的用户"
echo "------------"
USERTheSameUID=""
UIDs=$(cut -d: -f3 /etc/passwd | sort | uniq -c | awk '$1>1{print $2}')
for uid in $UIDs; do
echo -n "$uid"
USERTheSameUID="$uid"
r=$(awk -F: -v uid="$uid" '$3==uid{print ":",$1}' /etc/passwd)
echo "$r"
USERTheSameUID="$USERTheSameUID $r"
done
report_USERs="$USERs"
report_USEREmptyPassword="$USEREmptyPassword"
report_USERTheSameUID="$(echo $USERTheSameUID | sed 's/ $//')"
report_RootUser="$RootUser"
}
function getPasswordStatus(){
echo ""
echo ""
echo "############################ 密码检查 ############################"
pwdfile="$(cat /etc/passwd)"
echo ""
echo "密码过期检查"
echo "------------"
result=""
for shell in $(grep -v "/sbin/nologin" /etc/shells); do
for user in $(echo "$pwdfile" | grep "$shell" | cut -d: -f1); do
get_expiry_date=$(/usr/bin/chage -l $user | grep 'Password expires' | cut -d: -f2)
if [[ $get_expiry_date = ' never' || $get_expiry_date = 'never' ]]; then
printf "%-15s 永不过期
" $user
result="$result,$user:never"
else
password_expiry_date=$(date -d "$get_expiry_date" +%s)
current_date=$(date +%s)
diff=$((password_expiry_date-current_date))
let DAYS=$((diff/(60*60*24)))
printf "%-15s %s天后过期
" $user $DAYS
result="$result,$user:$DAYS days"
fi
done
done
report_PasswordExpiry="$(echo $result | sed 's/^,//')"
echo ""
echo "密码策略检查"
echo "------------"
grep -v "#" /etc/login.defs | grep -E "PASS_MAX_DAYS|PASS_MIN_DAYS|PASS_MIN_LEN|PASS_WARN_AGE"
}
function getSudoersStatus(){
echo ""
echo ""
echo "############################ Sudoers检查 #########################"
conf=$(grep -v "^#" /etc/sudoers | grep -v "^Defaults" | sed '/^$/d')
echo "$conf"
echo ""
report_Sudoers="$(echo $conf | wc -l)"
}
function getInstalledStatus(){
echo ""
echo ""
echo "############################ 软件检查 ############################"
rpm -qa --last | head | column -t
}
function getProcessStatus(){
echo ""
echo ""
echo "############################ 进程检查 ############################"
if [ $(ps -ef | grep defunct | grep -v grep | wc -l) -ge 1 ]; then
echo ""
echo "僵尸进程"
echo "--------"
ps -ef | head -n1
ps -ef | grep defunct | grep -v grep
fi
echo ""
echo "内存占用TOP10"
echo "-------------"
echo -e "PID %MEM RSS COMMAND
$(ps aux | awk '{print $2, $4, $6, $11}' | sort -k3rn | head -n 10)" | column -t
echo ""
echo "CPU占用TOP10"
echo "------------"
top -b -n1 | head -17 | tail -11
report_DefunctProsess="$(ps -ef | grep defunct | grep -v grep | wc -l)"
}
function getJDKStatus(){
echo ""
echo ""
echo "############################ JDK检查 #############################"
java -version 2>/dev/null
if [ $? -eq 0 ]; then
java -version 2>&1
fi
echo "JAVA_HOME=\"$JAVA_HOME\""
report_JDK="$(java -version 2>&1 | grep version | awk '{print $1,$3}' | tr -d '\"')"
}
function getSyslogStatus(){
echo ""
echo ""
echo "############################ syslog检查 ##########################"
echo "服务状态:$(getState rsyslog)"
echo ""
echo "/etc/rsyslog.conf"
echo "-----------------"
cat /etc/rsyslog.conf 2>/dev/null | grep -v "^#" | grep -v "^$" | sed '/^$/d' | column -t
report_Syslog="$(getState rsyslog)"
}
function getFirewallStatus(){
echo ""
echo ""
echo "############################ 防火墙检查 ##########################"
if [[ $centosVersion < 7 ]]; then
/etc/init.d/iptables status >/dev/null 2>&1
status=$?
if [ $status -eq 0 ]; then s="active"; elif [ $status -eq 3 ]; then s="inactive"; elif [ $status -eq 4 ]; then s="permission denied"; else s="unknown"; fi
else
s="$(getState iptables)"
fi
echo "iptables: $s"
echo ""
echo "/etc/sysconfig/iptables"
echo "-----------------------"
cat /etc/sysconfig/iptables 2>/dev/null
report_Firewall="$s"
}
function getSNMPStatus(){
echo ""
echo ""
echo "############################ SNMP检查 ############################"
status="$(getState snmpd)"
echo "服务状态:$status"
echo ""
if [ -e /etc/snmp/snmpd.conf ]; then
echo "/etc/snmp/snmpd.conf"
echo "--------------------"
cat /etc/snmp/snmpd.conf 2>/dev/null | grep -v "^#" | sed '/^$/d'
fi
report_SNMP="$status"
}
function getState(){
if [[ $centosVersion < 7 ]]; then
if [ -e "/etc/init.d/$1" ]; then
if [ `/etc/init.d/$1 status 2>/dev/null | grep -E "is running|正在运行" | wc -l` -ge 1 ]; then
r="active"
else
r="inactive"
fi
else
r="unknown"
fi
else
r="$(systemctl is-active $1 2>&1)"
fi
echo "$r"
}
function getSSHStatus(){
echo ""
echo ""
echo "############################ SSH检查 #############################"
echo "服务状态:$(getState sshd)"
Protocol_Version=$(cat /etc/ssh/sshd_config | grep Protocol | awk '{print $2}')
echo "SSH协议版本:$Protocol_Version"
echo ""
echo "信任主机"
echo "--------"
authorized=0
for user in $(echo "$pwdfile" | grep /bin/bash | awk -F: '{print $1}'); do
authorize_file=$(echo "$pwdfile" | grep -w $user | awk -F: '{printf $6"/.ssh/authorized_keys"}')
authorized_host=$(cat $authorize_file 2>/dev/null | awk '{print $3}' | tr '
' ',' | sed 's/,$//')
if [ ! -z $authorized_host ]; then
echo "$user 授权 \"$authorized_host\" 无密码访问"
fi
let authorized=authorized+$(cat $authorize_file 2>/dev/null | awk '{print $3}' | wc -l)
done
echo ""
echo "是否允许ROOT远程登录"
echo "--------------------"
config=$(cat /etc/ssh/sshd_config | grep PermitRootLogin)
firstChar=${config:0:1}
if [ $firstChar == "#" ]; then
PermitRootLogin="yes"
else
PermitRootLogin=$(echo $config | awk '{print $2}')
fi
echo "PermitRootLogin $PermitRootLogin"
echo ""
echo "/etc/ssh/sshd_config"
echo "--------------------"
cat /etc/ssh/sshd_config | grep -v "^#" | sed '/^$/d'
report_SSHAuthorized="$authorized"
report_SSHDProtocolVersion="$Protocol_Version"
report_SSHDPermitRootLogin="$PermitRootLogin"
}
function getNTPStatus(){
echo ""
echo ""
echo "############################ NTP检查 #############################"
if [ -e /etc/ntp.conf ]; then
echo "服务状态:$(getState ntpd)"
echo ""
echo "/etc/ntp.conf"
echo "-------------"
cat /etc/ntp.conf 2>/dev/null | grep -v "^#" | sed '/^$/d'
fi
report_NTP="$(getState ntpd)"
}
function check(){
version
getSystemStatus
getCpuStatus
getMemStatus
getDiskStatus
getNetworkStatus
getListenStatus
getProcessStatus
getServiceStatus
getAutoStartStatus
getLoginStatus
getCronStatus
getUserStatus
getPasswordStatus
getSudoersStatus
getJDKStatus
getFirewallStatus
getSSHStatus
getSyslogStatus
getSNMPStatus
getNTPStatus
getInstalledStatus
getchage_file_24h
}
#执行检查并保存检查结果
check > $RESULTFILE
echo "检查结果:$RESULTFILE"
echo -e "$(date "+%Y-%m-%d %H:%M:%S") 阿里云PHP企业平台巡检报告" | mail -a $RESULTFILE -s "阿里云PHP企业平台巡检报告" [email protected]Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
