Linux 服务器较为强大的运维及管理脚本实现(支援:本机线上操作)

发布时间:2023年12月18日

功能:

Copyright (C) 2019 ~ 2023 Sichuan Jiaile Network Information Technology Co., LTD. All rights reserved.
STG SCRIPT.(X) 1.0.0 VERSION

Usage:
? ? ./linux.sh make ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 编译
? ? ./linux.sh make ld ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?编译(LD)
? ? ./linux.sh make re ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?编译(RE)
? ? ./linux.sh git p ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Git ? ? ? ? : 拉取
? ? ./linux.sh git r ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Git ? ? ? ? : 变基
? ? ./linux.sh git ... ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Git ? ? ? ? : 命令
? ? ./linux.sh io cp ? ? ? ? ? ?[source]... [destination]... ? ? ? ? ?IO ? ? ? ? ?: 复制
? ? ./linux.sh io rm ? ? ? ? ? ?[source]... [destination]... ? ? ? ? ?IO ? ? ? ? ?: 删除
? ? ./linux.sh io mv ? ? ? ? ? ?[source]... [destination]... ? ? ? ? ?IO ? ? ? ? ?: 移动(文件)
? ? ./linux.sh io md ? ? ? ? ? ?[source]... [destination]... ? ? ? ? ?IO ? ? ? ? ?: 移动(目录)
? ? ./linux.sh io ll ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IO ? ? ? ? ?: 列表
? ? ./linux.sh sys ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OS
? ? ./linux.sh cmd ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?CMD
? ? ./linux.sh remote ? ? ? ? ? [user] [password] [host] [port] ... ? RPC
? ? ./linux.sh redis save ? ? ? [dump] ... ? ? ? ? ? ? ? ? ? ? ? ? ? ?Redis ? ? ? : 备份
? ? ./linux.sh mysql save ? ? ? [dump] ... ? ? ? ? ? ? ? ? ? ? ? ? ? ?MySQL ? ? ? : 备份
? ? ./linux.sh mysql save-all ? [dump] ... ? ? ? ? ? ? ? ? ? ? ? ? ? ?MySQL ? ? ? : 备份(全部)
? ? ./linux.sh server list ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?服务器 ? ? ?: 列出(全部)
? ? ./linux.sh server start ? ? [debug|release] ? ? ? ? ? ? ? ? ? ? ? 服务器 ? ? ?: 开服
? ? ./linux.sh server start-all [debug|release] ? ? ? ? ? ? ? ? ? ? ? 服务器 ? ? ?: 开服(全部)
? ? ./linux.sh server start-dev [debug|release] ? ? ? ? ? ? ? ? ? ? ? 服务器 ? ? ?: 开服(开发)
? ? ./linux.sh server stop ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?服务器 ? ? ?: 关闭
? ? ./linux.sh server stop-all ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?服务器 ? ? ?: 关闭(全部)
? ? ./linux.sh server pack ? ? ?[dump] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?服务器 ? ? ?: 打包
? ? ./linux.sh server pack-bin ?[dump] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?服务器 ? ? ?: 打包(程式)
? ? ./linux.sh server pack-res ?[dump] ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?服务器 ? ? ?: 打包(资源)
? ? ./linux.sh server publish ? [user] [password] [host] [port] ? ? ? 服务器 ? ? ?: 发布
? ? ./linux.sh server publish-clear ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 服务器 ? ? ?: 发布(清理)
? ? ./linux.sh help ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 帮助

#! /bin/bash

# Copyright  : Copyright (C) 2019 ~ 2023 Sichuan Jiaile Network Information Technology Co., LTD. All rights reserved.
# Description: STG SCRIPT.(X) 1.0.0 VERSION.
# Author     : Kyou.
# Date-Time  : 2023/12/13

STG_SCRIPT_NAME=$(basename "$0")
STG_BUILD_OPERATE_TYPE=$1
STG_BUILD_VERSION_TYPE=$2
STG_BUILD_C_TRHEAD_NUM=$3

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
SKYBLUE='\033[0;36m'
PLAIN='\033[0m'

# 编译线程数量,默认为12线程
if [ -z "$STG_BUILD_C_TRHEAD_NUM" ]; then
    STG_BUILD_C_TRHEAD_NUM=12
fi

# 编译版本类型,默认为调试版
if [[ "${STG_BUILD_VERSION_TYPE,,}" == "release" ]]; then
    STG_BUILD_VERSION_TYPE="release"
else
    STG_BUILD_VERSION_TYPE="debug"
fi

# 编译操作类型到小写字符串
STG_BUILD_OPERATE_TYPE=${STG_BUILD_OPERATE_TYPE,,}

# 编译工程解决方案(rebuild, tips) 
STG_build_executable() {
    local DONE_TIP_STRING='编译完成'
    local BEFO_TIP_STRING='正在编译'
    echo $BEFO_TIP_STRING

    # 清理服务器之前生成的程序
    local OPERATE_TYPE=$1
    OPERATE_TYPE=${OPERATE_TYPE,,}
    
    local REBUILD_OPERATE=false
    if [[ $OPERATE_TYPE == "ld" ]]; then
        local STG_BIN_EXE_DIR="Debug"
        if [[ $STG_BUILD_VERSION_TYPE == "release" ]]; then
            $STG_BIN_EXE_DIR="Release"
        fi

        rm -rf server/bin/$STG_BIN_EXE_DIR/GameServer
        rm -rf server/bin/$STG_BIN_EXE_DIR/GMServer
        rm -rf server/bin/$STG_BIN_EXE_DIR/LoginServer
        rm -rf server/bin/$STG_BIN_EXE_DIR/LoginServer
        rm -rf server/bin/$STG_BIN_EXE_DIR/Robot
        rm -rf server/bin/$STG_BIN_EXE_DIR/TestClient
    elif [[ $OPERATE_TYPE == "re" ]]; then
        REBUILD_OPERATE=true
    fi

    # 编译服务器引擎静态链接库
    cd code/ServerEngine/
    if $REBUILD_OPERATE; then
        rm -rf build/
    fi

    premake5 gmake
    cd build/
    make -j$STG_BUILD_C_TRHEAD_NUM config=$STG_BUILD_VERSION_TYPE

    # 编译全部的服务器程序代码
    cd ../../Server/
    if $REBUILD_OPERATE; then
        rm -rf build/
    fi

    premake5 gmake
    cd build/
    make -j$STG_BUILD_C_TRHEAD_NUM config=$STG_BUILD_VERSION_TYPE

    # 输出当前编译结束提示文本
    echo $DONE_TIP_STRING
}

# 变基解决方案代码
STG_rebase_code_sources() {
    echo '正在变基'

    # 主模块
    echo '源码...'
    git checkout .
    git clean -f -d
    git fetch
    git pull --rebase
    echo

    # 子模块
    echo '资源...'
    git checkout .
    git clean -f -d
    git fetch
    git pull --rebase

    echo '变基完成'
}

# 拉取解决方案代码
STG_pull_code_sources() {
    echo '正在拉取'

    # 主模块
    echo '源码...'
    git fetch
    git stash
    git pull
    git stash pop
    echo

    # 子模块
    echo '资源...'
    cd server/
    git fetch
    git stash
    git pull
    git stash pop

    echo '拉取完成'
}

# 显示脚本帮助信息
STG_help() {
    echo "Copyright (C) 2019 ~ 2023 Sichuan Jiaile Network Information Technology Co., LTD. All rights reserved."
    echo "STG SCRIPT.(X) 1.0.0 VERSION"
    echo 
    echo "Usage:"
    echo "    ./$STG_SCRIPT_NAME make                                                   编译"
    echo "    ./$STG_SCRIPT_NAME make ld                                                编译(LD)"
    echo "    ./$STG_SCRIPT_NAME make re                                                编译(RE)"

    echo "    ./$STG_SCRIPT_NAME git p                                                  Git         : 拉取"
    echo "    ./$STG_SCRIPT_NAME git r                                                  Git         : 变基"
    echo "    ./$STG_SCRIPT_NAME git ...                                                Git         : 命令"

    echo "    ./$STG_SCRIPT_NAME io cp            [source]... [destination]...          IO          : 复制"
    echo "    ./$STG_SCRIPT_NAME io rm            [source]... [destination]...          IO          : 删除"
    echo "    ./$STG_SCRIPT_NAME io mv            [source]... [destination]...          IO          : 移动(文件)"
    echo "    ./$STG_SCRIPT_NAME io md            [source]... [destination]...          IO          : 移动(目录)"
    echo "    ./$STG_SCRIPT_NAME io ll                                                  IO          : 列表"

    echo "    ./$STG_SCRIPT_NAME sys                                                    OS"
    echo "    ./$STG_SCRIPT_NAME cmd                                                    CMD"
    echo "    ./$STG_SCRIPT_NAME remote           [user] [password] [host] [port] ...   RPC"

    echo "    ./$STG_SCRIPT_NAME redis save       [dump] ...                            Redis       : 备份"
    echo "    ./$STG_SCRIPT_NAME mysql save       [dump] ...                            MySQL       : 备份"
    echo "    ./$STG_SCRIPT_NAME mysql save-all   [dump] ...                            MySQL       : 备份(全部)"

    echo "    ./$STG_SCRIPT_NAME server list                                            服务器      : 列出(全部)"
    echo "    ./$STG_SCRIPT_NAME server start     [debug|release]                       服务器      : 开服"
    echo "    ./$STG_SCRIPT_NAME server start-all [debug|release]                       服务器      : 开服(全部)"
    echo "    ./$STG_SCRIPT_NAME server start-dev [debug|release]                       服务器      : 开服(开发)"
    echo "    ./$STG_SCRIPT_NAME server stop                                            服务器      : 关闭"
    echo "    ./$STG_SCRIPT_NAME server stop-all                                        服务器      : 关闭(全部)"
    echo "    ./$STG_SCRIPT_NAME server pack      [dump]                                服务器      : 打包"
    echo "    ./$STG_SCRIPT_NAME server pack-bin  [dump]                                服务器      : 打包(程式)"
    echo "    ./$STG_SCRIPT_NAME server pack-res  [dump]                                服务器      : 打包(资源)"
    echo "    ./$STG_SCRIPT_NAME server publish   [user] [password] [host] [port]       服务器      : 发布"
    echo "    ./$STG_SCRIPT_NAME server publish-clear                                   服务器      : 发布(清理)"

    echo "    ./$STG_SCRIPT_NAME help                                                   帮助"
}

# 列出全部的服务器
STG_list_all_servers() {
    ps aux | 
        grep -E "./(Game|Login|GM|Proxy)Server" | 
            awk 'BEGIN {print "进程ID\tCPU负载\tCPU时间\t内存负载\t运行时间\t线程数\t进程名称\t配置文件"; flag=0} {cmd="ps -T -p "$2" | wc -l"; cmd|getline tnum; close(cmd); printf "%-10s %-8s %-10s %-10s %-12s %-8s %-20s %-20s\n", $2, $3"%", $10"%", $4"%", $9, tnum-1, $11, $13; flag=1} END {if (flag==0) {printf "%50s\n", "服务器未就绪!"}}' | 
                column -t
}

# 虚拟机环境的检查
STG_virt_check(){
    if hash ifconfig 2>/dev/null; then
        eth=$(ifconfig)
    fi

    virtualx=$(dmesg) 2>/dev/null
    if  [ $(which dmidecode) ]; then
        sys_manu=$(dmidecode -s system-manufacturer) 2>/dev/null
        sys_product=$(dmidecode -s system-product-name) 2>/dev/null
        sys_ver=$(dmidecode -s system-version) 2>/dev/null
    else
        sys_manu=""
        sys_product=""
        sys_ver=""
    fi
    
    if grep docker /proc/1/cgroup -qa; then
        virtual="Docker"
    elif grep lxc /proc/1/cgroup -qa; then
        virtual="Lxc"
    elif grep -qa container=lxc /proc/1/environ; then
        virtual="Lxc"
    elif [[ -f /proc/user_beancounters ]]; then
        virtual="OpenVZ"
    elif [[ "$virtualx" == *kvm-clock* ]]; then
        virtual="KVM"
    elif [[ "$cname" == *KVM* ]]; then
        virtual="KVM"
    elif [[ "$cname" == *QEMU* ]]; then
        virtual="KVM"
    elif [[ "$virtualx" == *"VMware Virtual Platform"* ]]; then
        virtual="VMware"
    elif [[ "$virtualx" == *"Parallels Software International"* ]]; then
        virtual="Parallels"
    elif [[ "$virtualx" == *VirtualBox* ]]; then
        virtual="VirtualBox"
    elif [[ -e /proc/xen ]]; then
        virtual="Xen"
    elif [[ "$sys_manu" == *"Microsoft Corporation"* ]]; then
        if [[ "$sys_product" == *"Virtual Machine"* ]]; then
            if [[ "$sys_ver" == *"7.0"* || "$sys_ver" == *"Hyper-V" ]]; then
                virtual="Hyper-V"
            else
                virtual="Microsoft Virtual Machine"
            fi
        fi
    else
        virtual="Dedicated"
    fi
    
    echo $virtual
}

# 计算设备磁盘大小
STG_calc_disk_size() {
    local total_size=0
    local array=$@
    for size in ${array[@]}
    do
        [ "${size}" == "0" ] && size_t=0 || size_t=`echo ${size:0:${#size}-1}`
        [ "`echo ${size:(-1)}`" == "K" ] && size=0
        [ "`echo ${size:(-1)}`" == "M" ] && size=$(awk 'BEGIN{printf "%.1f", '$size_t' / 1024}')
        [ "`echo ${size:(-1)}`" == "T" ] && size=$(awk 'BEGIN{printf "%.1f", '$size_t' * 1024}')
        [ "`echo ${size:(-1)}`" == "G" ] && size=${size_t}
        total_size=$(awk 'BEGIN{printf "%.1f", '$total_size' + '$size'}')
    done
    echo ${total_size}
}

# 查看工作主机信息
STG_sys() {
    # 显示CPU型号、主频、物理核心数、逻辑核心数、CPU缓存大小
    cpu_model=$(grep "model name" /proc/cpuinfo | head -n1 | awk -F: '{print $2}' | xargs)
    cpu_freq=$(lscpu | grep "CPU MHz" | awk '{printf "%.3f MHz\n", $3}')
    phy_cores=$(lscpu | grep "Core(s) per socket" | awk '{print $4}')
    logic_cores=$(lscpu | grep "^CPU(s):" | awk '{print $2}')
    cpu_cache=$(lscpu | grep "L3 cache" | awk '{gsub(/K/," "); printf "%s KB\n", $NF}')
    cpu_arch=$(lscpu | grep "Architecture" | awk '{print $2}')

    # 显示内存总量和当前使用的内存(单位:MB)
    memory_total=$(free -m | awk '/^Mem:/ {print $2}')
    memory_used=$(free -m | awk '/^Mem:/ {print $3}')
    memory_bram=$(free -m | awk '/^Mem:/ {print $6}')

    # 显示总磁盘空间和已用磁盘空间(单位:GB)
    disk_size1=$(LANG=C df -hPl | grep -wvE '\-|none|tmpfs|overlay|shm|udev|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $2}')
    disk_size2=$(LANG=C df -hPl | grep -wvE '\-|none|tmpfs|overlay|shm|udev|devtmpfs|by-uuid|chroot|Filesystem' | awk '{print $3}')
    disk_total=$(STG_calc_disk_size ${disk_size1[@]})
    disk_used=$(STG_calc_disk_size ${disk_size2[@]})

    # 显示总交换区大小和当前使用的交换区(单位:MB)
    swap_total=$(free -m | awk '/^Swap:/ {print $2}')
    swap_used=$(free -m | awk '/^Swap:/ {print $3}')

    # 显示当前TCP控制协议
    tcp_congestion=$(sysctl net.ipv4.tcp_congestion_control | awk -F'=' '{print $2}' | xargs)

    # 显示当前系统信息和内核版本
    system_info=$(cat /etc/*-release | head -n1)
    kernel_version=$(uname -r)

    # 显示当前的uptime
    uptime_raw=$(cut -d " " -f1 /proc/uptime)
    uptime_days=$(echo "$uptime_raw/60/60/24" | bc)
    uptime_hours=$(echo "$uptime_raw/60/60%24" | bc) #$((uptime_raw/60/60%24))
    uptime_minutes=$(echo "$uptime_raw/60%24" | bc) #$((uptime_raw/60%60))
    uptime_formatted="${uptime_days} days ${uptime_hours} hours ${uptime_minutes} min"

    # 打印输出
    echo -e "CPU Model    : ${SKYBLUE}$cpu_model${PLAIN}"
    echo -e "CPU Cores    : ${YELLOW}$phy_cores Cores $logic_cores Threads ${SKYBLUE}$cpu_freq $cpu_arch${PLAIN}"
    echo -e "CPU Cache    : ${SKYBLUE}$cpu_cache${PLAIN}"
    echo -e "OS           : ${SKYBLUE}$system_info${PLAIN} $YELLOW$(STG_virt_check)$PLAIN"
    echo -e "OS Time      : ${SKYBLUE}$(date +"%Y-%m-%d %H:%M:%S %Z")${PLAIN}"
    echo -e "Kernel       : ${SKYBLUE}$kernel_version${PLAIN}"

    echo -e "Total Space  : ${SKYBLUE}${disk_used} GB / ${YELLOW}${disk_total} GB ${PLAIN}"
    echo -e "Total RAM    : ${SKYBLUE}${memory_used} MB / ${YELLOW}${memory_total} MB${PLAIN} ${SKYBLUE}(${memory_bram} MB Buff)${PLAIN}"
    echo -e "Total Swap   : ${SKYBLUE}${swap_used} MB / ${YELLOW}${swap_total} MB${PLAIN}"
    
    echo -e "Uptime       : ${SKYBLUE}$uptime_formatted${PLAIN}"
    echo -e "TCP CC       : ${YELLOW}$tcp_congestion${PLAIN}"
}

# 停止指定的服务器
STG_stop_server_by_pid_and_name() {
    local PID=$1
    local NAME=$2
    local CONF=$3
    if [[ -z $CONF ]]; then
        CONF="config is <none>"
    else
        CONF="config is $CONF"
    fi

    echo -n "KILL: [$PID] $NAME ${CONF} "
    kill -SIGUSR1 $PID
    while pgrep -x "$CLASS_TYPE" | grep $PID >/dev/null; do
        sleep 1
        echo -n "."
    done
    echo " [OK]"
}

# 停止所有的服务器(某一类)
STG_stop_all_servers_by_class() {
    local CLASS_TYPE=$1
    local PROC_LIST=$(ps aux | grep -E "./($CLASS_TYPE)" | grep -v grep)

    echo "$PROC_LIST" | while read LINE; do
        if [ -n "$LINE" ]; then
            local PID=$(echo "$LINE" | awk '{print $2}')
            local NAME=$(echo "$LINE" | awk '{print $11}')
            local CONF=$(echo "$LINE" | awk '{print $13}')
            STG_stop_server_by_pid_and_name $PID $NAME $CONF
        fi
    done
}

# 开启服务器(指定)
STG_start_server_by_exe_path() {
    local EXE_PATH=$2
    local CONF_PATH=$3
    if test -f $EXE_PATH; then
        if test -f $CONF_PATH; then
            local START_CMD="$EXE_PATH"
            if $1; then
                START_CMD="$START_CMD -daemon"
            fi

            # 输出正在启动进程信息
            echo -n "START: $EXE_PATH"

            # 输出当前配置文件名
            if [[ -z $CONF_PATH ]]; then
                echo -n " config is <none> "
            else
                START_CMD="$START_CMD $CONF_PATH"
                echo -n " config is $CONF_PATH "
            fi

            # 程序是否已经在运行
            if ps -ef | grep -v grep | grep "$START_CMD" > /dev/null; then
                echo -n " ... [RE]"
            else
                # 先延迟等待三秒之后
                $START_CMD > /dev/null 2>&1
                for ((i=0; i<3; i++)); do
                    echo -n "."
                    sleep 1
                done

                # 确定服务器是否正确开启
                if ps -ef | grep "$START_CMD" | grep -v grep > /dev/null; then
                    echo -n " [OK]"
                else
                    echo -n " [ER]"
                fi
            fi
            echo
        fi
    fi
}

# 开启服务器(全部)
STG_start_all_servers() {
    local OPERATE_TYPE=$2
    OPERATE_TYPE=${OPERATE_TYPE,,}

    if [[ $OPERATE_TYPE == "release" ]]; then
        OPERATE_TYPE="Release"
    else
        OPERATE_TYPE="Debug"
    fi

    # 运行代理服务器
    if [[ $1 -eq 1 ]]; then
        if [ -d ProxyServer/ ]; then
            cd ProxyServer/
            STG_start_server_by_exe_path false ./ProxyServer
            cd ../
        else
            echo "代理服务器程式,目录不存在!"
            return 0
        fi
    fi

    # 切程序目录
    if [ -d server/bin/$OPERATE_TYPE ]; then
        cd server/bin/$OPERATE_TYPE
    elif [ -d server/bin/ ]; then
        cd server/bin/
    else
        echo "游戏服务器程式,目录不存在!"
        return 0
    fi

    # 前置服务器
    STG_start_server_by_exe_path true "./GMServer"
    STG_start_server_by_exe_path true "./GameServer" "../../config/Distributed-Center.json"
    STG_start_server_by_exe_path true "./GameServer" "../../config/Distributed-Arena.json"

    # 游戏服务器
    for config_file in $(find ../../config/ -name 'Distributed-Game*.json' 2>/dev/null); do
        STG_start_server_by_exe_path true "./GameServer" $config_file
    done

    # 战斗服务器
    STG_start_server_by_exe_path true "./GameServer" "../../config/Distributed-Battle.json"

    # 登入服务器
    if [[ $1 -eq 2 ]]; then
        STG_start_server_by_exe_path true "./LoginServer" "../../config/Distributed-Login.json" 
    else
        for config_file in $(find ../../config/ -name 'Distributed-Login*.json' 2>/dev/null); do
            STG_start_server_by_exe_path true "./LoginServer" $config_file
        done
    fi
    return 1
}

# 服务器打包
STG_server_package() {
    local PACKAGE_NAME=$2
    if [ -z $PACKAGE_NAME ]; then
        PACKAGE_NAME="$(date +%Y%m%d_%H%M%S)"
    fi

    # 打包程序
    if [[ $1 -eq 0 ]] || [[ $1 -eq 1 ]]; then
        cd server/bin/Release/
        tar jcvf ../../../bin_$PACKAGE_NAME.tar.bz2 GameServer GMServer LoginServer
        cd ../../../
    fi

    # 打包资源
    if [[ $1 -eq 0 ]] || [[ $1 -eq 2 ]]; then
        cd server/
        zip -r ../res_$PACKAGE_NAME.zip fbs/ sql/ data/ script/
        cd ../
    fi
}

# 服务器资源发布(清理)
STG_server_publish_clear() {
    find ./ -name 'res_*.zip' -type f -delete
    find ./ -name 'bin_*.tar.bz2' -type f -delete
}

# 服务器资源发布
STG_server_publish() { # [host] [user] [password]
    local USER=$1
    local PASS=$2
    local HOST=$3
    local PORT=$4
    if [ -z $PORT ]; then
        PORT=22
    fi

    # 检查参数
    if [ -z $USER ] || [ -z $PASS ] || [ -z $HOST ]; then
        echo "用户名、密码或主机地址不可以为空!"
        return 0
    fi 

    # 搜索资源
    local file_res=$(find ./ -name 'res_*.zip' 2>/dev/null)
    local file_bin=$(find ./ -name 'bin_*.tar.bz2' 2>/dev/null)
    if [ -z $file_res ] && [ -z $file_bin ]; then
        STG_server_package 0

        file_res=$(find ./ -name 'res_*.zip' 2>/dev/null)
        file_bin=$(find ./ -name 'bin_*.tar.bz2' 2>/dev/null)
        if [ -z $file_res ] && [ -z $file_bin ]; then
            echo "重新打包失败!"
            return 0
        fi
    fi

    # 复制程序
    for file in $file_bin; do
        echo "SCP: $file"
        sshpass -p $PASS scp -P $PORT -r $file $USER@$HOST:/root/stg
    done

    # 复制资源
    for file in $file_res; do
        echo "SCP: $file"
        sshpass -p $PASS scp -P $PORT -r $file $USER@$HOST:/root/stg
    done

    # 复制本脚本到远程服务器上
    sshpass -p $PASS scp -P $PORT -r ./$STG_SCRIPT_NAME $USER@$HOST:/root/stg

    # 在远程服务器上解压缩文件
    sshpass -p $PASS ssh -p $PORT $USER@$HOST "cd /root/stg/ && chmod a+x ./$STG_SCRIPT_NAME && ./$STG_SCRIPT_NAME -------------------------publish-unpack-------------------------"
}

# 服务器发布解包(内部命令)
STG_publish_unpack() {
    # 解压程序
    local file_bin=$(find ./ -name 'bin_*.tar.bz2' 2>/dev/null)
    for file in $file_bin; do
        echo "UNPACK: $file"
        cd server/bin/

        # 解压程序
        if [ -d Release/ ]; then
            cd Release/
            tar jxvf ../../../$file --overwrite
            cd ../../../
        else
            tar jxvf ../../$file --overwrite
            cd ../../
        fi

        # 删除文件
        rm -rf $file
    done

    # 解压资源
    local file_res=$(find ./ -name 'res_*.zip' 2>/dev/null)
    for file in $file_res; do
        echo "UNPACK: $file"
        cd server/
        unzip -o ../$file
        cd ../
        rm -rf $file
    done
}

# 服务器命令操作
STG_server() {
    local OPERATE_TYPE=$1
    OPERATE_TYPE=${OPERATE_TYPE,,}

    if [[ $OPERATE_TYPE == "list" ]]; then 
        STG_list_all_servers
    elif [[ $OPERATE_TYPE == "start" ]]; then 
        STG_start_all_servers 0 $2
    elif [[ $OPERATE_TYPE == "start-all" ]]; then 
        STG_start_all_servers 1 $2
    elif [[ $OPERATE_TYPE == "start-dev" ]]; then 
        STG_start_all_servers 2 $2
    elif [[ $OPERATE_TYPE == "stop" ]]; then 
        STG_stop_all_servers_by_class "LoginServer"
        STG_stop_all_servers_by_class "GameServer"
        STG_stop_all_servers_by_class "GMServer"
    elif [[ $OPERATE_TYPE == "stop-all" ]]; then 
        STG_stop_all_servers_by_class "LoginServer"
        STG_stop_all_servers_by_class "GameServer"
        STG_stop_all_servers_by_class "GMServer"
        STG_stop_all_servers_by_class "ProxyServer"
    elif [[ $OPERATE_TYPE == "pack" ]]; then
        STG_server_package 0 $2
    elif [[ $OPERATE_TYPE == "pack-bin" ]]; then
        STG_server_package 1 $2
    elif [[ $OPERATE_TYPE == "pack-res" ]]; then
        STG_server_package 2 $2
    elif [[ $OPERATE_TYPE == "publish" ]]; then
        STG_server_publish "${@:2}"
    elif [[ $OPERATE_TYPE == "publish-clear" ]]; then
        STG_server_publish_clear
    elif [[ $OPERATE_TYPE == "-------------------------publish-unpack-------------------------" ]]; then 
        STG_publish_unpack
    else
        STG_list_all_servers
    fi
}

# GIT命令操作
STG_git() {
    local OPERATE_TYPE=$1
    OPERATE_TYPE=${OPERATE_TYPE,,}

    if [[ $OPERATE_TYPE == "r" ]]; then
        STG_rebase_code_sources
    elif [[ $OPERATE_TYPE == "p" ]]; then
        STG_pull_code_sources
    elif [ -n "$OPERATE_TYPE" ]; then
        git "${@:1}"
    else
        git status
    fi
}

# 文件操作
STG_io() {
    local OPERATE_TYPE=$1
    OPERATE_TYPE=${OPERATE_TYPE,,}

    if [[ $OPERATE_TYPE == "cp" ]]; then
        yes | cp -rf "${@:2}" > /dev/null 2>&1
    elif [[ $OPERATE_TYPE == "rm" ]]; then 
        yes | rm -rf "${@:2}" > /dev/null 2>&1
    elif [[ $OPERATE_TYPE == "mv" ]]; then
        yes | mv -f "${@:2}" > /dev/null 2>&1
    elif [[ $OPERATE_TYPE == "md" ]]; then
        yes | mv -T -f "${@:2}" > /dev/null 2>&1
    elif [[ $OPERATE_TYPE == "ll" ]]; then
        ls -al
    elif [ -n "$OPERATE_TYPE" ]; then
        ${@:1}
    else
        ls -al
    fi
}

# MYSQL数据库备份
STG_mysql_dump_all_dbs() {
    local MYSQL_DUMP_CMD="mysqldump ${@:3}" 
    if [ -z ${@:3} ]; then
        if [ "$1" = "true" ]; then
            option="save-all"
        else
            option="save"
        fi
        
        echo "Usage:"
        echo "    ./$STG_SCRIPT_NAME mysql $option ./dump_$(date +%Y%m%d_%H%M%S).sql -uroot -h10.10.10.10 -ptest"
        return 0
    fi

    if $1; then
        MYSQL_DUMP_CMD="$MYSQL_DUMP_CMD --databases stg_account stg_game"
    else
        MYSQL_DUMP_CMD="$MYSQL_DUMP_CMD --all-databases"
    fi

    local MYSQL_DUMP_FN=$2
    if [ -z $MYSQL_DUMP_FN ]; then
        MYSQL_DUMP_FN="./dump_$(date +%Y%m%d_%H%M%S).sql"
    fi

    MYSQL_DUMP_CMD="$MYSQL_DUMP_CMD > $MYSQL_DUMP_FN > /dev/null 2>&1"
    $MYSQL_DUMP_CMD 
    return 1
}

# 数据库操作
STG_mysql() {
    local OPERATE_TYPE=$1
    OPERATE_TYPE=${OPERATE_TYPE,,}

    if [[ $OPERATE_TYPE == "save" ]]; then
        STG_mysql_dump_all_dbs false "${@:2}"
    elif [[ $OPERATE_TYPE == "save-all" ]]; then
        STG_mysql_dump_all_dbs true "${@:2}"
    else
        echo "操作不支持!"
    fi
}

# 远程执行命令
STG_remote() {
    local USER=$1
    local PASS=$2
    local HOST=$3
    local PORT=$4
    if [ -z $PORT ]; then
        PORT=22
    fi

    # 检查参数
    if [ -z $USER ] || [ -z $PASS ] || [ -z $HOST ]; then
        echo "Usage:"
        echo "    ./$STG_SCRIPT_NAME remote root test 10.10.10.10"
        echo "    ./$STG_SCRIPT_NAME remote root test 10.10.10.10 22 server list"
        return 0
    fi 

    # 复制本脚本到远程服务器上
    sshpass -p $PASS scp -P $PORT -r ./$STG_SCRIPT_NAME $USER@$HOST:/root/stg

    # 在远程服务器上解压缩文件
    sshpass -p $PASS ssh -p $PORT $USER@$HOST "cd /root/stg/ && chmod a+x ./$STG_SCRIPT_NAME && ./$STG_SCRIPT_NAME ${@:5}"
}

# 在本机执行命令
STG_cmd() {
    ${@:1}
}

# 重新编译解决方案
if [[ $STG_BUILD_OPERATE_TYPE == "make" ]]; then
    STG_build_executable "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "git" ]]; then
    STG_git "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "io" ]]; then
    STG_io "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "cmd" ]]; then
    STG_cmd "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "sys" ]]; then
    STG_sys "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "mysql" ]]; then
    STG_mysql "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "server" ]]; then
    STG_server "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "remote" ]]; then
    STG_remote "${@:2}"
else
    STG_help "${@:2}"
fi

文章来源:https://blog.csdn.net/liulilittle/article/details/135023421
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。