Matters needing attention

1) Add the interpreter at the beginning: #! /bin/bash

2) Syntax indent, use four Spaces; Add some notes.

3) Naming suggestion rules: variable names in uppercase, local variables in lowercase, function names in lowercase, names reflect the actual effect.

4) The default variable is global. In the function, the variable local is specified as a local variable to avoid contaminating other scopes.

5) There are two commands to help me debug the script: set-e exits the script on non-zero execution, and set-x prints the execution.

6) Scripts must be tested before production.

1. Obtain random strings or numbers

Get a random 8-bit string:
Method 1:# echo $RANDOM |md5sum |cut -c 1-8471b94F2 Method 2:# openssl rand -base64 4Vg3BEg == method 3:# cat /proc/sys/kernel/random/uuid |cut -c 1-8
ed9e032c
Copy the code
Get random 8-digit numbers:
Method 1:# echo $RANDOM |cksum |cut -c 1-8Method 2:# openssl rand -base64 4 |cksum |cut -c 1-8Method 3:# date +%N |cut -c 1-8
69024815Copy the code

Cksum: prints the CRC effect and statistics bytes

2. Define a color output string function


Method 1:function echo_color() {
    if [ The $1= ="green" ]; then
        echo -e "\033[32;40m$2\033[0m"
    elif [ The $1= ="red" ]; then
        echo -e "\033[31;40m$2\033[0m"
    fi} Method 2:function echo_color() {
    case The $1 in
        green)
            echo -e "\033[32;40m$2\033[0m"
            ;;
        red)
            echo -e "\033[31;40m$2\033[0m" 
            ;;
        *) 
            echo "Example: echo_color red string"
    esac} Use method: echo_color green"test"Copy the code

The function keyword defines a function, which may or may not be added.

3. Create users in batches

#! /bin/bash
DATE=$(date +%F_%T)
USER_FILE=user.txt
echo_color() {if [ The $1= ="green" ]; then
        echo -e "\033[32;40m$2\033[0m"
    elif [ The $1= ="red" ]; then
        echo -e "\033[31;40m$2\033[0m"
    fi
}
If the user file exists and the size is greater than 0, back it up
if [ -s $USER_FILE ]; then
    mv $USER_FILE ${USER_FILE}-${DATE}.bak
    echo_color green "$USER_FILE exist, rename ${USER_FILE}-${DATE}.bak"
fi
echo -e "User\tPassword" >> $USER_FILE
echo "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -" >> $USER_FILE
for USER inuser{1.. 10};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 -e "$USER\t$PASS" >> $USER_FILE
        echo "$USER User create successful."
    else
        echo_color red "$USER User already exists!"
    fi
done
Copy the code

4. Check whether the software package is installed

#! /bin/bash
if rpm -q sysstat &>/dev/null; then
    echo "sysstat is already installed."
else
    echo "sysstat is not installed!"
fi
Copy the code

5. Check the service status

#! /bin/bash
PORT_C=$(ss -anu |grep -c 123)
PS_C=$(ps -ef |grep ntpd |grep -vc grep)
if [ $PORT_C -eq 0 -o $PS_C -eq0];then
    echo "Content" | mail -s "Theme" [email protected]
fi
Copy the code

6. Check the host survival status

Method 1: Put the wrong IP into the array to determine whether the ping failed three times
#! /bin/bash
IP_LIST="192.168.18.1 192.168.1.1 192.168.18.2"
for IP in $IP_LIST; do
    NUM=1
    while [ $NUM -le 3 ]; do
        if ping -c 1 $IP > /dev/null; then
            echo "$IP Ping is successful."
            break
        else
            # echo "$IP Ping is failure $NUM"
            FAIL_COUNT[$NUM] =$IP
            let NUM++
        fi
    done
    if [ ${#FAIL_COUNT[*]} -eq3];then
        echo "${FAIL_COUNT[1]} Ping is failure!"
        unset FAIL_COUNT[*]
    fi
done
Copy the code
Method 2: Add the number of errors to the FAIL_COUNT variable to determine whether the ping fails three times
#! /bin/bash
IP_LIST="192.168.18.1 192.168.1.1 192.168.18.2"
for IP in $IP_LIST; do
    FAIL_COUNT=0
    for((i=1; i<=3; i++));do
        if ping -c 1 $IP >/dev/null; then
            echo "$IP Ping is successful."
            break
        else
            # echo "$IP Ping is failure $i"
            let FAIL_COUNT++
        fi
    done
    if [ $FAIL_COUNT -eq3];then
        echo "$IP Ping is failure!"
    fi
done
Copy the code
Method 3: Use the for loop to ping through and then jump out of the loop and continue. If not, the ping will fail to print
#! /bin/bash
ping_success_status() {
    if ping -c 1 $IP >/dev/null; then
        echo "$IP Ping is successful."
        continue
    fi
}
IP_LIST="192.168.18.1 192.168.1.1 192.168.18.2"
for IP in $IP_LIST; do
    ping_success_status
    ping_success_status
    ping_success_status
    echo "$IP Ping is failure!"
done
Copy the code

7. Monitor CPU, memory, and disk usage

1) the CPU

Analyze CPU statistics with the vmstat tool.

#! /bin/bash
DATE=$(date +%F""%H:%M)
IP=$(ifconfig eth0 |awk -F '[ :]+' '/inet addr/{print $4}')  Only CentOS6 is supported
MAIL="[email protected]"
if ! which vmstat &>/dev/null; then
    echo "vmstat command no found, Please install procps package." 
    exit 1
fi
US=$(vmstat |awk 'NR==3{print $13}')
SY=$(vmstat |awk 'NR==3{print $14}')
IDLE=$(vmstat |awk 'NR==3{print $15}')
WAIT=$(vmstat |awk 'NR==3{print $16}')
USE=$(($US+$SY))
if [ $USE -ge 50 ]; then
    echo "
    Date: $DATE
    Host: $IP
    Problem: CPU utilization $USE
    " | mail -s "CPU Monitor" $MAIL
fi
Copy the code
2) memory
#! /bin/bash
DATE=$(date +%F""%H:%M)
IP=$(ifconfig eth0 |awk -F '[ :]+' '/inet addr/{print $4}')  
MAIL="[email protected]"
TOTAL=$(free -m |awk '/Mem/{print $2}')
USE=$(free -m |awk '/Mem/{print $3-$6-$7}')
FREE=$(($TOTAL-$USE))
If the memory is less than 1G, send an alarm email
if [ $FREE -lt1024];then
    echo "
    Date: $DATE
    Host: $IP
    Problem: Total=$TOTAL,Use=$USE,Free=$FREE
    " | mail -s "Memory Monitor" $MAIL
fi
Copy the code
3) the hard disk
#! /bin/bash
DATE=$(date +%F""%H:%M)
IP=$(ifconfig eth0 |awk -F '[ :]+' '/inet addr/{print $4}')  
MAIL="[email protected]"
TOTAL=$(fdisk -l |awk -F'[: ]+' 'BEGIN{OFS="="}/^Disk \/dev/{printf "%s=%sG,",$2,$3}')
PART_USE=$(df -h |awk 'BEGIN{OFS="="}/^\/dev/{print $1,int($5),$6}')
for i in $PART_USE; do
    PART=$(echo $i |cut -d"=" -f1)
    USE=$(echo $i |cut -d"=" -f2)
    MOUNT=$(echo $i |cut -d"=" -f3)
    if [ $USE -gt80];then
        echo "
        Date: $DATE
        Host: $IP
        Total: $TOTAL
        Problem: $PART=$USE($MOUNT)" | mail -s "Disk Monitor" $MAIL
    fi
done
Copy the code

8. Monitor disk usage of hosts in batches

Prerequisites The monitoring end and the monitored end do not need to log in to each other using SSH or by key.

Write a configuration file in the format of IP User Port to save SSH connection information of the monitored host

#! /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 $1,int($5)}' $TMP_FILE)
    for USE_RATE in $USE_RATE_LIST; do
        PART_NAME=${USE_RATE%=*}
        USE_RATE=${USE_RATE#*=}
        if [ $USE_RATE -ge 80 ]; then
            echo "Warning: $PART_NAME Partition usage $USE_RATE%!"
        fi
    done
done
Copy the code

9. Check website usability

1) Check URL availability
Method 1:check_url() {
    HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" The $1)
    if [ $HTTP_CODE -ne200];then
        echo "Warning: The $1 Access failure!"
    fi} Method 2:check_url() {
if ! wget -T 10 --tries=1 --spider The $1 >/dev/null 2>&1; then  
-t timeout, --tries 1 time, --spider mode
        echo "Warning: The $1 Access failure!"
    fi
}Copy the code

Usage: check_url www.baidu.com

2) Judge URL availability three times

The procedure is the same as the above procedure for checking the host survival status.

Method 1: Use the loop technique, break out of the current loop if successful, otherwise go to the last line#! /bin/bash
check_url() {
    HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" The $1)
    if [ $HTTP_CODE -eq200];then
        continue
    fi
}
URL_LIST="www.baidu.com www.agasgf.com"
for URL in $URL_LIST; do
    check_url $URL
    check_url $URL
    check_url $URL
    echo "Warning: $URL Access failure!"
done
Copy the code
Method 2: Save the number of errors to a variable#! /bin/bash
URL_LIST="www.baidu.com www.agasgf.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 -ne200];then
            let FAIL_COUNT++
        else
            break
        fi
    done
    if [ $FAIL_COUNT -eq3];then
        echo "Warning: $URL Access failure!"
    fi
done
Copy the code
Method 3: Save the error count to an array#! /bin/bash
URL_LIST="www.baidu.com www.agasgf.com"
for URL in $URL_LIST; do
    NUM=1
    while [ $NUM -le 3 ]; do
        HTTP_CODE=$(curl -o /dev/null --connect-timeout 3 -s -w "%{http_code}" $URL)
        if [ $HTTP_CODE -ne200];then
            FAIL_COUNT[$NUM] =$IP  Create an array with $NUM subscript and $IP element
            let NUM++
        else
            break
        fi
    done
    if [ ${#FAIL_COUNT[*]} -eq3];then
        echo "Warning: $URL Access failure!"
        unset FAIL_COUNT[*]    # empty array
    fi
done
Copy the code

10. Check the primary/secondary synchronization status of MySQL

#! /bin/bash
USER=bak
PASSWD=123456
IO_SQL_STATUS=$(mysql -u$USER -p$PASSWD -e 'show slave status\G' |awk -F: '/Slave_.*_Running/{gsub(": ",":"); print $0}')  #gsub Removes the space after the colon
for i in $IO_SQL_STATUS; do
    THREAD_STATUS_NAME=${i%:*}
    THREAD_STATUS=${i#*:}
    if [ "$THREAD_STATUS"! ="Yes" ]; then
        echo "Error: MySQL Master-Slave $THREAD_STATUS_NAME status is $THREAD_STATUS!"
    fi
done
Copy the code


This chapter to write Shell script examples are more practical, in the interview questions also often appear, I hope you refer to more hands-on writing, do not copy and paste to run, this is not to learn!