Bash Script: Check Server Resources


1 đoạn bash script giúp bạn kiểm tra thông số server, các dịch vụ cơ bản được cài đặt trên server.

Kiểm tra nhanh LEMP stack
Quick Command
curl -sSL https://go.nguyenanhung.com/server-report | bash
server-report.sh
#!/bin/bash
# Get the script's filename without path
directory_name=$(dirname "$0")
script_name=$(basename "$0")
# Generate a unique lock file name by combining the directory name and script name,
# converting them to lowercase, replacing spaces and non-alphanumeric characters with hyphens,
locked_name="${directory_name}-${script_name}-by-${USER}"
locked_name=$(echo "$locked_name" | tr '[:upper:]' '[:lower:]') # Convert to lowercase
locked_name=$(echo "$locked_name" | sed -E 's/[^a-z0-9]+/-/g')  # Replace spaces and non-alphanumeric characters with hyphens
locked_name=$(echo "$locked_name" | sed -E 's/^-+|-+$//g')      # Remove any extra hyphens at the beginning or end of the string
mkdir -p /tmp/hungng-locked && chmod 0777 /tmp/hungng-locked
locked_filename="/tmp/hungng-locked/${locked_name}.lock"
# Lock the script so that only one instance can run at a time.
exec 200>"${locked_filename}" || exit 1
flock -n 200 || exit 1
##################################################################################
#    _    _                     _   _                                            #
#   | |  | |                   | \ | |                                           #
#   | |__| |_   _ _ __   __ _  |  \| | __ _ _   _ _   _  ___ _ __                #
#   |  __  | | | | '_ \ / _` | | . ` |/ _` | | | | | | |/ _ \ '_ \               #
#   | |  | | |_| | | | | (_| | | |\  | (_| | |_| | |_| |  __/ | | |              #
#   |_|  |_|\__,_|_| |_|\__, | |_| \_|\__, |\__,_|\__, |\___|_| |_|              #
#                        __/ |         __/ |       __/ |                         #
#                       |___/         |___/       |___/                          #
#--------------------------------------------------------------------------------#
#                       BEAR Manage Server Script Configure                      #
# Manage Server by Hung Nguyen - [email protected] - https://nguyenanhung.com #
# Any copying without written permission is a violation of copyright policy!     #
##################################################################################
DEVELOP_BY="Hung Nguyen - [email protected]"
SCRIPT_VERSION="2.0.4"
# Bash variables
export NC='\033[0m'
export RED='\033[0;31m'
export GREEN='\033[0;32m'
export YELLOW='\033[0;33m'
export CYAN='\033[0;36m'
export NAVAJO_WHITE='\033[38;5;223m' # Navajo white
print_message() {
  local LINE="----------------------------------------------------------------------"
  if [ "$1" = "" ]; then
    echo
    echo "$LINE"
    echo
  else
    echo
    echo "$LINE"
    echo -e "${CYAN}$1${NC}"
    echo "$LINE"
    echo
  fi
}
message() {
  local level
  level=$(echo "$1" | tr '[:lower:]' '[:upper:]')
  local message=$2
  # Color
  local RSC='\033[0m'
  local FATAL='\033[1;41m\033[1;33m'  # Nền đỏ - chữ vàng
  local ERROR='\033[41m\033[1;37m'    # Nền đỏ - Màu trắng đậm
  local FAILED='\033[0;31m'           # Màu đỏ
  local INFO='\033[0;92m'             # Màu xanh lá nhạt
  local DEBUG='\033[0;35m'            # Magenta
  local TRACE='\033[35m'              # Magenta
  local EMERGENCY='\033[41;1m'        # Màu nền đỏ đậm nhấp nháy
  local CRITICAL='\033[41m\033[1;32m' # Xanh lá cây đậm - Nền đỏ
  local ALERT='\033[1;31m'            # Màu cam đậm
  local WARNING='\033[0;33m'          # Màu vàng
  local NOTICE='\033[0;36m'           # Màu xanh dương nhạt
  local SUCCESS='\033[1;36m'          # Cyan đậm
  local LINK='\033[1;34m'             # Blue đậm
  local SUGGEST='\033[38;5;223m'      # Navajo white
  # Write message
  case $level in
  FATAL) echo -e "${level}: ${FATAL}${message}${RSC}" ;;
  ERROR | ERR) echo -e "${level}: ${ERROR}${message}${RSC}" ;;
  FAILED) echo -e "${level}: ${FAILED}${message}${RSC}" ;;
  WARN | WARNING) echo -e "${level}: ${WARNING}${message}${RSC}" ;;
  INFO) echo -e "${level}: ${INFO}${message}${RSC}" ;;
  SUCCESS | FINISHED) echo -e "${level}: ${SUCCESS}${message}${RSC}" ;;
  LINK | URL) echo -e "${level}: ${LINK}${message}${RSC}" ;;
  DEBUG) echo -e "${level}: ${DEBUG}${message}${RSC}" ;;
  TRACE | CURRENT) echo -e "${level}: ${TRACE}${message}${RSC}" ;;
  EMERGENCY) echo -e "${level}: ${EMERGENCY}${message}${RSC}" ;;
  ALERT) echo -e "${level}: ${ALERT}${message}${RSC}" ;;
  CRITICAL) echo -e "${level}: ${CRITICAL}${message}${RSC}" ;;
  NOTICE | NOTE) echo -e "${level}: ${NOTICE}${message}${RSC}" ;;
  SUGGEST) echo -e "${level}: ${SUGGEST}${message}${RSC}" ;;
  *) echo -e "${message}" ;;
  esac
}
has_command() {
  command -v "$1" &>/dev/null
}
os_detect() {
  local os="Unknown"
  if [[ "$(uname)" == "Darwin" ]]; then
    os="MacOS"
  elif [[ -f /etc/os-release ]]; then
    source /etc/os-release
    case "$ID" in
    rhel | centos | rocky | rockylinux | almalinux | fedora)
      os="RHEL"
      ;;
    ubuntu | linuxmint | debian)
      os="Ubuntu"
      ;;
    alpine)
      os="Alpine"
      ;;
    opensuse)
      os="OpenSUSE"
      ;;
    sles)
      os="SLES"
      ;;
    esac
  elif command -v lsb_release &>/dev/null; then
    local distro
    distro=$(lsb_release -si)
    case "$distro" in
    Ubuntu | LinuxMint | Debian)
      os="Ubuntu"
      ;;
    Fedora | CentOS | RedHatEnterpriseServer | Rocky | RockyLinux | AlmaLinux)
      os="RHEL"
      ;;
    openSUSE)
      os="OpenSUSE"
      ;;
    SUSE)
      os="SLES"
      ;;
    esac
  fi
  echo "$os"
}
is_installed() {
  local package_name=$1
  if [[ -z "$package_name" ]]; then
    message ERROR "Package name is required."
    return 1
  fi
  if command -v rpm &>/dev/null; then
    if rpm -q "$package_name" &>/dev/null; then
      return 0
    else
      return 1
    fi
  elif command -v dpkg-query &>/dev/null; then
    if dpkg-query -W -f='${Status}' "$package_name" 2>/dev/null | grep -q "installed"; then
      return 0
    else
      return 1
    fi
  else
    message ERROR "Unsupported package manager."
    return 1
  fi
}
install_need_package() {
  local package=$1
  if command -v dnf &>/dev/null; then
    sudo dnf install -y "$package"
  elif command -v yum &>/dev/null; then
    sudo yum install -y "$package"
  elif command -v apt &>/dev/null; then
    sudo apt install -y "$package"
  else
    echo "Unsupported package manager. Please install $package manually."
    return 1
  fi
}
install_package() {
  if ! is_installed "$1"; then
    print_message "Installing package $1"
    if install_need_package "$1"; then
      message INFO "Package $1 installed successfully!"
    else
      message ERROR "Error installing package $1!"
    fi
  fi
}
install_required_scripts() {
  install_package bc
}
install_required_scripts
display_script_information() {
  local SCRIPT_NAME
  SCRIPT_NAME=${1:-"BEAR Manage Server Script"}
  echo "==========================================================="
  echo
  echo "  _    _                           _   _    _____ "
  echo " | |  | |                         | \ | |  / ____|"
  echo " | |__| |  _   _   _ __     __ _  |  \| | | |  __ "
  echo " |  __  | | | | | | '_ \   / _\` | | . \` | | | |_ |"
  echo " | |  | | | |_| | | | | | | (_| | | |\  | | |__| |"
  echo " |_|  |_|  \__,_| |_| |_|  \__, | |_| \_|  \_____|"
  echo "                            __/ |                 "
  echo "                           |___/                  "
  echo
  echo -e "Powered by ${NAVAJO_WHITE}${DEVELOP_BY}${NC}"
  echo
  echo -e "${GREEN}${SCRIPT_NAME}${NC} - version ${YELLOW}${SCRIPT_VERSION}${NC}"
  echo
  echo "==========================================================="
}
display_script_information "Script Check Server Resources"
calculator_disk() {
  local total_size=0
  local size_t size unit
  local array=("$@") # Lưu toàn bộ tham số vào mảng

  for size in "${array[@]}"; do
    size_t="${size:0:${#size}-1}" # Lấy phần số
    unit="${size:(-1)}"           # Lấy ký tự cuối cùng làm đơn vị

    # Chuyển đổi các đơn vị
    case "$unit" in
    M) size=$(awk 'BEGIN{printf "%.1f", '"$size_t"' / 1024}') ;; # Từ MB -> GB
    T) size=$(awk 'BEGIN{printf "%.1f", '"$size_t"' * 1024}') ;; # Từ TB -> GB
    G) size="$size_t" ;;                                         # GB không cần thay đổi
    *) size=0 ;;                                                 # Nếu đơn vị không phải M, G, T thì coi như 0
    esac

    # Cộng kích thước vào tổng
    total_size=$(awk 'BEGIN{printf "%.1f", '"$total_size"' + '"$size"'}')
  done

  echo "${total_size}"
}
count_processes_by_user() {
  # Input: $1 is the user to check
  local check_user=$1

  # Check if user is provided
  if [[ -z "$check_user" ]]; then
    echo 0 # Return 0 if no user is provided
    return
  fi

  # Count processes by user, including threads
  local process_count
  process_count=$(ps -eLf | awk -v pattern="$1" '$0 ~ pattern {count++} END {print count}')

  # Output the result
  echo "$process_count"
}
fetch_public_ip() {
  local CHECK_URL IP
  for CHECK_URL in "https://checkip.amazonaws.com/" "https://icanhazip.com/" "https://whatismyip.akamai.com/" "https://api.ipify.org/" "https://cpanel.net/showip.cgi" "https://myip.directadmin.com/" "https://ipinfo.io/ip"; do
    IP=$(curl -s --max-time 1 "${CHECK_URL}") && [ -n "${IP}" ] && echo "${IP}" && return 0
  done
  return 1
}
########################################################################################################################
cpu_name=$(awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')
cpu_cores=$(awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo)
cpu_freq=$(awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//')
cpu_load=$(grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage "%"}')
cpu_bogo_mips=$(lscpu | grep 'BogoMIPS:' | awk '{print $2}')
cpu_cache_l1=$(lscpu | grep 'L1d' | awk '{print $3 " " $4}')
cpu_cache_l2=$(lscpu | grep 'L2' | awk '{print $3 " " $4}')
cpu_cache_l3=$(lscpu | grep 'L3' | awk '{print $3 " " $4}')
server_ram_total=$(awk '/MemTotal/ {print $2}' /proc/meminfo)
server_ram_mb=$(echo "scale=0;$server_ram_total/1024" | bc)
total_ram=$(free -m | awk '/Mem/ {print $2}')
used_ram=$(free -m | awk '/Mem/ {print $3}')
ram_usage_percent=$(((used_ram * 100) / total_ram))
total_swap=$(free -m | awk '/Swap/ {print $2}')
used_swap=$(free -m | awk '/Swap/ {print $3}')
if [ "$total_swap" -eq 0 ]; then
  swap_usage_percent=0
else
  swap_usage_percent=$(((used_swap * 100) / total_swap))
fi
#server_hdd=$(df -h | awk 'NR==5 {print $2}')
free_hdd=$(df -h | awk 'NR==5 {print $4}')
disk_size1=$(LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $2}')
disk_size2=$(LANG=C df -hPl | grep -wvE '\-|none|tmpfs|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $3}')
disk_total_size=$(calculator_disk "${disk_size1[@]}")
disk_used_size=$(calculator_disk "${disk_size2[@]}")
disk_used_percent=$(df -h / | tail -n 1 | awk '{print $5}')
free_hdd_size=$(calculator_disk "${free_hdd[@]}")
#server_swap_total=$(awk '/SwapTotal/ {print $2}' /proc/meminfo)
#server_swap_mb=$(echo "scale=0;$server_swap_total/1024" | bc)
max_children=$(echo "scale=0;$server_ram_mb*0.4/30" | bc)
min_spare_server=$((cpu_cores * 2))
max_spare_server=$((cpu_cores * 4))
pm_start_servers=$((min_spare_server + (max_spare_server - min_spare_server) / 2))
server_os_compatibility=$(grep '^ID_LIKE=' /etc/os-release | cut -d= -f2- | tr -d '"')
os_compatibility="${server_os_compatibility^^}"
os_name=$(grep '^PRETTY_NAME=' /etc/os-release | cut -d= -f2- | tr -d '"')
server_os_virtualization=$(hostnamectl | grep "Virtualization" | awk '{print $2}')
os_virtualization="${server_os_virtualization^^}"
ServerIPv4="$(ip addr show | awk '/inet / && !/127.0.0.1/ {print $2}' | cut -d'/' -f1 | grep -Ev '^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1]))')"
ServerIPv6="$(ip addr show | awk '/inet6/ && !/scope link/ {print $2}' | cut -d'/' -f1 | grep -vE '^fe80|^::1')"
########################################################################################################################
print_message
message INFO "Date                        : ${YELLOW}$(date)${NC} - ${GREEN}$(date "+%Y-%m-%d %H:%M:%S")${NC}"
message INFO "Server Public IP v4         : ${YELLOW}$(fetch_public_ip)${NC}"
message INFO "Server IP v4 Address        : ${YELLOW}${ServerIPv4}${NC}"
message INFO "Server IP v6 Address        : ${YELLOW}${ServerIPv6}${NC}"
message INFO "CPU model                   : ${YELLOW}$cpu_name${NC}"
message INFO "Number of cores             : ${YELLOW}$cpu_cores${NC}"
message INFO "CPU frequency               : ${YELLOW}$cpu_freq${NC} MHz"
message INFO "CPU usage load              : ${YELLOW}$cpu_load${NC}"
message INFO "CPU BogoMIPS                : ${YELLOW}$cpu_bogo_mips${NC}"
message INFO "CPU L1 Cache                : ${YELLOW}$cpu_cache_l1${NC}"
message INFO "CPU L2 Cache                : ${YELLOW}$cpu_cache_l2${NC}"
message INFO "CPU L3 Cache                : ${YELLOW}$cpu_cache_l3${NC}"
message INFO "Max Children                : ${YELLOW}$max_children${NC}"
message INFO "Start Servers               : ${YELLOW}$pm_start_servers${NC}"
message INFO "Min Spare Server            : ${YELLOW}$min_spare_server${NC}"
message INFO "Max Spare Server            : ${YELLOW}$max_spare_server${NC}"
message INFO "Total size of Disk          : ${YELLOW}$disk_total_size${NC} GB (Used: ${GREEN}${disk_used_percent}${NC} [${NAVAJO_WHITE}${disk_used_size}${NC} GB] - Available: ${GREEN}${free_hdd_size}${NC} GB)${NC}"
message INFO "Total amount of Memory      : ${YELLOW}$total_ram${NC} MB (Used: ${GREEN}${ram_usage_percent}${NC}% - ${NAVAJO_WHITE}$used_ram${NC} MB)"
message INFO "Total amount of Swap        : ${YELLOW}$total_swap${NC} MB (Used: ${GREEN}${swap_usage_percent}${NC}% - ${NAVAJO_WHITE}$used_swap${NC} MB)"
message INFO "OS Name                     : ${YELLOW}${os_name}${NC}"
message INFO "OS Architecture             : ${YELLOW}$(uname -m)${NC}"
message INFO "OS Kernel Version           : ${YELLOW}$(uname -r)${NC}"
message INFO "OS Virtualization           : ${YELLOW}$os_virtualization${NC}"
message INFO "OS Compatibility            : ${YELLOW}$os_compatibility${NC}"
message INFO "System Uptime               : ${YELLOW}$(awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60} {printf("%d days, %d hour %d min\n",a,b,c)}' /proc/uptime)${NC}"
message INFO "Load average                : ${YELLOW}$(w | head -1 | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//')${NC}"
message INFO "Users logged                : ${YELLOW}$(who | wc -l)${NC}"
message INFO "Total process running       : ${YELLOW}$(ps aux | wc -l)${NC}"
if has_command mysql; then
  message INFO "MySQL                       : ${NC}Process running: ${YELLOW}$(count_processes_by_user "mysql")${NC} - Version: ${GREEN}$(mysql -V | awk '{gsub(/,/, "", $5); print $5}')${NC}"
fi
if has_command php-fpm; then
  WP_CLI_Version=""
  if has_command wp; then
    WP_CLI_Version=" - WP-CLI version: ${GREEN}$(wp --info | grep "WP-CLI version" | awk '{print $3}')${NC}"
  fi
  message INFO "PHP Information             : ${NC}Process running: ${YELLOW}$(count_processes_by_user "php-fpm")${NC} - Path to PHP: ${YELLOW}$(which php)${NC} - PHP version: ${GREEN}$(php -v | awk '/^PHP/{print $2}')${NC} ${WP_CLI_Version}"
fi
if has_command nginx; then
  message INFO "Nginx                       : ${NC}Process running: ${YELLOW}$(count_processes_by_user "nginx")${NC} - Version: ${GREEN}$(nginx -v 2>&1 | awk -F'/' '{print $2}')${NC}"
fi
if is_installed nginx-amplify-agent; then
  message INFO "Nginx Amplify agent running : ${YELLOW}$(count_processes_by_user "amplify-agent")${NC}"
fi
if has_command httpd; then
  message INFO "Apache                      : ${NC}Process running: ${YELLOW}$(count_processes_by_user "apache")${NC} - Version: ${GREEN}$(httpd -v | awk '/^Server version:/{print $3, $4, $5}')${NC}"
fi
if has_command perl; then
  if command -v rpm &>/dev/null; then
    perl_version=$(rpm -q perl)
  elif command -v dpkg-query &>/dev/null; then
    perl_version=$(dpkg-query -W perl | awk '{print $2}')
  else
    perl_version=""
  fi
  message INFO "Perl Information            : ${NC}Process running: ${YELLOW}$(count_processes_by_user "perl")${NC} - Path to Perl: ${YELLOW}$(which perl)${NC} - Perl version: ${GREEN}${perl_version}${NC}"
fi
if has_command redis-cli; then
  message INFO "Redis                       : ${NC}Process running: ${YELLOW}$(count_processes_by_user "redis")${NC} - Version: ${GREEN}$(redis-server --version | awk '{print $3}' | cut -d "=" -f 2)${NC}"
fi
if is_installed memcached; then
  message INFO "Memcached                   : ${NC}Process running: ${YELLOW}$(count_processes_by_user "memcached")${NC} - Version: ${GREEN}$(memcached -V | awk '{print $2}')${NC}"
fi
if has_command gearmand; then
  message INFO "Gearmand                    : ${NC}Process running: ${YELLOW}$(count_processes_by_user "gearmand")${NC} - Version: ${GREEN}$(gearmand --version | awk '{print $2}')${NC}"
fi
if has_command supervisord; then
  message INFO "Supervisord                 : ${NC}Process running: ${YELLOW}$(count_processes_by_user "supervisord")${NC} - Version: ${GREEN}$(supervisord -v)${NC}"
fi
if has_command gitlab-runner; then
  message INFO "Gitlab-Runner               : ${NC}Process running: ${YELLOW}$(count_processes_by_user "gitlab-runner")${NC} - Version: ${GREEN}$(gitlab-runner --version | grep "Version" | awk '{print $2}')${NC}"
fi
if has_command docker; then
  message INFO "Docker                      : ${NC}Process running: ${YELLOW}$(count_processes_by_user "docker")${NC} - ${GREEN}$(docker --version)${NC}"
  print_message
  docker ps
  print_message
fi
print_message "Check storage on your server"

# Function to check if a device is HDD or SSD
check_storage_type() {
  # Get the list of devices and their rotational flag (ROTA)
  local devices_info device rota
  devices_info=$(lsblk -d -o name,rota | tail -n +2) # Skip the header

  # Iterate through each device and check if it's HDD or SSD
  while read -r device rota; do
    if [[ "$rota" -eq 1 ]]; then
      printf "INFO: ${GREEN}%-27s${NC} : ${YELLOW}%-50s${NC} \n" "Storage '$device' is" "HDD Disk"
    elif [[ "$rota" -eq 0 ]]; then
      printf "INFO: ${GREEN}%-27s${NC} : ${YELLOW}%-50s${NC} \n" "Storage '$device' is" "SSD Disk"
    else
      printf "INFO: ${GREEN}%-27s${NC} : ${YELLOW}%-50s${NC} \n" "Storage '$device' is" "Unknown type"
    fi
  done <<<"$devices_info"
}

# Run the function
check_storage_type

print_message "Finished"
unset NAVAJO_WHITE CYAN YELLOW GREEN RED NC
full-width

Post a Comment

Mới hơn Cũ hơn