Linux 服务器较为强大的运维及管理脚本实现(支援:本机线上操作)
功能:
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/13STG_SCRIPT_NAME=$(basename "$0")
STG_BUILD_OPERATE_TYPE=$1
STG_BUILD_VERSION_TYPE=$2
STG_BUILD_C_TRHEAD_NUM=$3RED='\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" ]; thenSTG_BUILD_C_TRHEAD_NUM=12
fi# 编译版本类型,默认为调试版
if [[ "${STG_BUILD_VERSION_TYPE,,}" == "release" ]]; thenSTG_BUILD_VERSION_TYPE="release"
elseSTG_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=$1OPERATE_TYPE=${OPERATE_TYPE,,}local REBUILD_OPERATE=falseif [[ $OPERATE_TYPE == "ld" ]]; thenlocal STG_BIN_EXE_DIR="Debug"if [[ $STG_BUILD_VERSION_TYPE == "release" ]]; then$STG_BIN_EXE_DIR="Release"firm -rf server/bin/$STG_BIN_EXE_DIR/GameServerrm -rf server/bin/$STG_BIN_EXE_DIR/GMServerrm -rf server/bin/$STG_BIN_EXE_DIR/LoginServerrm -rf server/bin/$STG_BIN_EXE_DIR/LoginServerrm -rf server/bin/$STG_BIN_EXE_DIR/Robotrm -rf server/bin/$STG_BIN_EXE_DIR/TestClientelif [[ $OPERATE_TYPE == "re" ]]; thenREBUILD_OPERATE=truefi# 编译服务器引擎静态链接库cd code/ServerEngine/if $REBUILD_OPERATE; thenrm -rf build/fipremake5 gmakecd build/make -j$STG_BUILD_C_TRHEAD_NUM config=$STG_BUILD_VERSION_TYPE# 编译全部的服务器程序代码cd ../../Server/if $REBUILD_OPERATE; thenrm -rf build/fipremake5 gmakecd 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 -dgit fetchgit pull --rebaseecho# 子模块echo '资源...'git checkout .git clean -f -dgit fetchgit pull --rebaseecho '变基完成'
}# 拉取解决方案代码
STG_pull_code_sources() {echo '正在拉取'# 主模块echo '源码...'git fetchgit stashgit pullgit stash popecho# 子模块echo '资源...'cd server/git fetchgit stashgit pullgit stash popecho '拉取完成'
}# 显示脚本帮助信息
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; theneth=$(ifconfig)fivirtualx=$(dmesg) 2>/dev/nullif [ $(which dmidecode) ]; thensys_manu=$(dmidecode -s system-manufacturer) 2>/dev/nullsys_product=$(dmidecode -s system-product-name) 2>/dev/nullsys_ver=$(dmidecode -s system-version) 2>/dev/nullelsesys_manu=""sys_product=""sys_ver=""fiif grep docker /proc/1/cgroup -qa; thenvirtual="Docker"elif grep lxc /proc/1/cgroup -qa; thenvirtual="Lxc"elif grep -qa container=lxc /proc/1/environ; thenvirtual="Lxc"elif [[ -f /proc/user_beancounters ]]; thenvirtual="OpenVZ"elif [[ "$virtualx" == *kvm-clock* ]]; thenvirtual="KVM"elif [[ "$cname" == *KVM* ]]; thenvirtual="KVM"elif [[ "$cname" == *QEMU* ]]; thenvirtual="KVM"elif [[ "$virtualx" == *"VMware Virtual Platform"* ]]; thenvirtual="VMware"elif [[ "$virtualx" == *"Parallels Software International"* ]]; thenvirtual="Parallels"elif [[ "$virtualx" == *VirtualBox* ]]; thenvirtual="VirtualBox"elif [[ -e /proc/xen ]]; thenvirtual="Xen"elif [[ "$sys_manu" == *"Microsoft Corporation"* ]]; thenif [[ "$sys_product" == *"Virtual Machine"* ]]; thenif [[ "$sys_ver" == *"7.0"* || "$sys_ver" == *"Hyper-V" ]]; thenvirtual="Hyper-V"elsevirtual="Microsoft Virtual Machine"fifielsevirtual="Dedicated"fiecho $virtual
}# 计算设备磁盘大小
STG_calc_disk_size() {local total_size=0local 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'}')doneecho ${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)# 显示当前的uptimeuptime_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=$1local NAME=$2local CONF=$3if [[ -z $CONF ]]; thenCONF="config is <none>"elseCONF="config is $CONF"fiecho -n "KILL: [$PID] $NAME ${CONF} "kill -SIGUSR1 $PIDwhile pgrep -x "$CLASS_TYPE" | grep $PID >/dev/null; dosleep 1echo -n "."doneecho " [OK]"
}# 停止所有的服务器(某一类)
STG_stop_all_servers_by_class() {local CLASS_TYPE=$1local PROC_LIST=$(ps aux | grep -E "./($CLASS_TYPE)" | grep -v grep)echo "$PROC_LIST" | while read LINE; doif [ -n "$LINE" ]; thenlocal 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 $CONFfidone
}# 开启服务器(指定)
STG_start_server_by_exe_path() {local EXE_PATH=$2local CONF_PATH=$3if test -f $EXE_PATH; thenif test -f $CONF_PATH; thenlocal START_CMD="$EXE_PATH"if $1; thenSTART_CMD="$START_CMD -daemon"fi# 输出正在启动进程信息echo -n "START: $EXE_PATH"# 输出当前配置文件名if [[ -z $CONF_PATH ]]; thenecho -n " config is <none> "elseSTART_CMD="$START_CMD $CONF_PATH"echo -n " config is $CONF_PATH "fi# 程序是否已经在运行if ps -ef | grep -v grep | grep "$START_CMD" > /dev/null; thenecho -n " ... [RE]"else# 先延迟等待三秒之后$START_CMD > /dev/null 2>&1for ((i=0; i<3; i++)); doecho -n "."sleep 1done# 确定服务器是否正确开启if ps -ef | grep "$START_CMD" | grep -v grep > /dev/null; thenecho -n " [OK]"elseecho -n " [ER]"fifiechofifi
}# 开启服务器(全部)
STG_start_all_servers() {local OPERATE_TYPE=$2OPERATE_TYPE=${OPERATE_TYPE,,}if [[ $OPERATE_TYPE == "release" ]]; thenOPERATE_TYPE="Release"elseOPERATE_TYPE="Debug"fi# 运行代理服务器if [[ $1 -eq 1 ]]; thenif [ -d ProxyServer/ ]; thencd ProxyServer/STG_start_server_by_exe_path false ./ProxyServercd ../elseecho "代理服务器程式,目录不存在!"return 0fifi# 切程序目录if [ -d server/bin/$OPERATE_TYPE ]; thencd server/bin/$OPERATE_TYPEelif [ -d server/bin/ ]; thencd server/bin/elseecho "游戏服务器程式,目录不存在!"return 0fi# 前置服务器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); doSTG_start_server_by_exe_path true "./GameServer" $config_filedone# 战斗服务器STG_start_server_by_exe_path true "./GameServer" "../../config/Distributed-Battle.json"# 登入服务器if [[ $1 -eq 2 ]]; thenSTG_start_server_by_exe_path true "./LoginServer" "../../config/Distributed-Login.json" elsefor config_file in $(find ../../config/ -name 'Distributed-Login*.json' 2>/dev/null); doSTG_start_server_by_exe_path true "./LoginServer" $config_filedonefireturn 1
}# 服务器打包
STG_server_package() {local PACKAGE_NAME=$2if [ -z $PACKAGE_NAME ]; thenPACKAGE_NAME="$(date +%Y%m%d_%H%M%S)"fi# 打包程序if [[ $1 -eq 0 ]] || [[ $1 -eq 1 ]]; thencd server/bin/Release/tar jcvf ../../../bin_$PACKAGE_NAME.tar.bz2 GameServer GMServer LoginServercd ../../../fi# 打包资源if [[ $1 -eq 0 ]] || [[ $1 -eq 2 ]]; thencd server/zip -r ../res_$PACKAGE_NAME.zip fbs/ sql/ data/ script/cd ../fi
}# 服务器资源发布(清理)
STG_server_publish_clear() {find ./ -name 'res_*.zip' -type f -deletefind ./ -name 'bin_*.tar.bz2' -type f -delete
}# 服务器资源发布
STG_server_publish() { # [host] [user] [password]local USER=$1local PASS=$2local HOST=$3local PORT=$4if [ -z $PORT ]; thenPORT=22fi# 检查参数if [ -z $USER ] || [ -z $PASS ] || [ -z $HOST ]; thenecho "用户名、密码或主机地址不可以为空!"return 0fi # 搜索资源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 ]; thenSTG_server_package 0file_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 ]; thenecho "重新打包失败!"return 0fifi# 复制程序for file in $file_bin; doecho "SCP: $file"sshpass -p $PASS scp -P $PORT -r $file $USER@$HOST:/root/stgdone# 复制资源for file in $file_res; doecho "SCP: $file"sshpass -p $PASS scp -P $PORT -r $file $USER@$HOST:/root/stgdone# 复制本脚本到远程服务器上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; doecho "UNPACK: $file"cd server/bin/# 解压程序if [ -d Release/ ]; thencd Release/tar jxvf ../../../$file --overwritecd ../../../elsetar jxvf ../../$file --overwritecd ../../fi# 删除文件rm -rf $filedone# 解压资源local file_res=$(find ./ -name 'res_*.zip' 2>/dev/null)for file in $file_res; doecho "UNPACK: $file"cd server/unzip -o ../$filecd ../rm -rf $filedone
}# 服务器命令操作
STG_server() {local OPERATE_TYPE=$1OPERATE_TYPE=${OPERATE_TYPE,,}if [[ $OPERATE_TYPE == "list" ]]; then STG_list_all_serverselif [[ $OPERATE_TYPE == "start" ]]; then STG_start_all_servers 0 $2elif [[ $OPERATE_TYPE == "start-all" ]]; then STG_start_all_servers 1 $2elif [[ $OPERATE_TYPE == "start-dev" ]]; then STG_start_all_servers 2 $2elif [[ $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" ]]; thenSTG_server_package 0 $2elif [[ $OPERATE_TYPE == "pack-bin" ]]; thenSTG_server_package 1 $2elif [[ $OPERATE_TYPE == "pack-res" ]]; thenSTG_server_package 2 $2elif [[ $OPERATE_TYPE == "publish" ]]; thenSTG_server_publish "${@:2}"elif [[ $OPERATE_TYPE == "publish-clear" ]]; thenSTG_server_publish_clearelif [[ $OPERATE_TYPE == "-------------------------publish-unpack-------------------------" ]]; then STG_publish_unpackelseSTG_list_all_serversfi
}# GIT命令操作
STG_git() {local OPERATE_TYPE=$1OPERATE_TYPE=${OPERATE_TYPE,,}if [[ $OPERATE_TYPE == "r" ]]; thenSTG_rebase_code_sourceselif [[ $OPERATE_TYPE == "p" ]]; thenSTG_pull_code_sourceselif [ -n "$OPERATE_TYPE" ]; thengit "${@:1}"elsegit statusfi
}# 文件操作
STG_io() {local OPERATE_TYPE=$1OPERATE_TYPE=${OPERATE_TYPE,,}if [[ $OPERATE_TYPE == "cp" ]]; thenyes | cp -rf "${@:2}" > /dev/null 2>&1elif [[ $OPERATE_TYPE == "rm" ]]; then yes | rm -rf "${@:2}" > /dev/null 2>&1elif [[ $OPERATE_TYPE == "mv" ]]; thenyes | mv -f "${@:2}" > /dev/null 2>&1elif [[ $OPERATE_TYPE == "md" ]]; thenyes | mv -T -f "${@:2}" > /dev/null 2>&1elif [[ $OPERATE_TYPE == "ll" ]]; thenls -alelif [ -n "$OPERATE_TYPE" ]; then${@:1}elsels -alfi
}# MYSQL数据库备份
STG_mysql_dump_all_dbs() {local MYSQL_DUMP_CMD="mysqldump ${@:3}" if [ -z ${@:3} ]; thenif [ "$1" = "true" ]; thenoption="save-all"elseoption="save"fiecho "Usage:"echo " ./$STG_SCRIPT_NAME mysql $option ./dump_$(date +%Y%m%d_%H%M%S).sql -uroot -h10.10.10.10 -ptest"return 0fiif $1; thenMYSQL_DUMP_CMD="$MYSQL_DUMP_CMD --databases stg_account stg_game"elseMYSQL_DUMP_CMD="$MYSQL_DUMP_CMD --all-databases"filocal MYSQL_DUMP_FN=$2if [ -z $MYSQL_DUMP_FN ]; thenMYSQL_DUMP_FN="./dump_$(date +%Y%m%d_%H%M%S).sql"fiMYSQL_DUMP_CMD="$MYSQL_DUMP_CMD > $MYSQL_DUMP_FN > /dev/null 2>&1"$MYSQL_DUMP_CMD return 1
}# 数据库操作
STG_mysql() {local OPERATE_TYPE=$1OPERATE_TYPE=${OPERATE_TYPE,,}if [[ $OPERATE_TYPE == "save" ]]; thenSTG_mysql_dump_all_dbs false "${@:2}"elif [[ $OPERATE_TYPE == "save-all" ]]; thenSTG_mysql_dump_all_dbs true "${@:2}"elseecho "操作不支持!"fi
}# 远程执行命令
STG_remote() {local USER=$1local PASS=$2local HOST=$3local PORT=$4if [ -z $PORT ]; thenPORT=22fi# 检查参数if [ -z $USER ] || [ -z $PASS ] || [ -z $HOST ]; thenecho "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 0fi # 复制本脚本到远程服务器上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" ]]; thenSTG_build_executable "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "git" ]]; thenSTG_git "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "io" ]]; thenSTG_io "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "cmd" ]]; thenSTG_cmd "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "sys" ]]; thenSTG_sys "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "mysql" ]]; thenSTG_mysql "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "server" ]]; thenSTG_server "${@:2}"
elif [[ $STG_BUILD_OPERATE_TYPE == "remote" ]]; thenSTG_remote "${@:2}"
elseSTG_help "${@:2}"
fi
相关文章:
Linux 服务器较为强大的运维及管理脚本实现(支援:本机线上操作)
功能: 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 …...

【数据结构】插入排序,希尔排序,选择排序,堆排序,冒泡排序
1.插入排序 思路:插入排序将一个数插入一个有序的数组里面,将这个数和数组元素挨着比较,直到他插入到合适的位置。 动画演示: 步骤:1.定义一个变量tmp保存要插入的数据 2.在循环中用tmp和有序数组中的元素比较&#…...

MyBatis--07--启动过程分析、SqlSession安全问题、拦截器
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 谈谈MyBatis的启动过程具体的操作过程如下:实现测试类,并测试SqlSessionFactorySqlSession SqlSession有数据安全问题?在MyBatis中,SqlSess…...

Qt基础之四十二:QMap、QHash的实现原理和性能对比
一.红黑树与哈希表 1.红黑树 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的。 红黑树为了保证其最长…...
虚幻学习笔记12—C++类的实例化
一、前言 本系列如无特殊说明使用的虚幻版本都是5.2.1,VS为2022版本。在Unity中通常创建的脚本都默认继承了MonoBehavior,都是不能再用代码New而实例化的,虚幻也是一样不能直接New来实例化。在Unity中是通过Instantiate方法来实例化一个游戏对…...
【《漫画算法》笔记】快速排序
非递归实现 使用集合栈代替递归的函数栈 public static void main(String[] args) {int[] arrnew int[]{4,4,6,4,3,2,8,1}; // int[] arrnew int[]{3,2}; // quickSort1(arr,0,arr.length-1); // recursive, double sides // quickSort2(arr,0,arr.lengt…...
C++如何通过调用ffmpeg接口对H265文件进行编码和解码
要对H265文件进行编码和解码,需要使用FFmpeg库提供的相关API。以下是一个简单的C程序,演示如何使用FFmpeg进行H265文件的编码和解码: 编码: #include <cstdlib> #include <cstdio> #include <cstring> #inclu…...
8位LED流水灯设计
一、实验目的 本实验为设计性实验,要求理解和掌握触发器、译码器、时序脉冲、LED显示单元的工作原理与功能,通过设计和制作8位的LED流水灯电路,综合运用触发器和译码器等逻辑器件及显示单元进行功能性时序逻辑电路的设计和制作,掌握时序逻辑电路的基本设计和调试方法。 二、…...

eclipse连接mysql数据库(下载eclipse,下载安装mysql,下载mysql驱动)
前言: 使用版本:eclipse2017,mysql5.7.0,MySQL的jar建议使用最新的,可以避免警告! 1:下载安装:eclipse,mysql在我之前博客中有 http://t.csdnimg.cn/UW5fshttp://t.csdn…...

【信息学奥赛】拼在起跑线上,想入道就别落下自己!
编程无难事,只怕有心人,学就是了! 文章目录 1 信息学奥赛简介2 信息学竞赛的经验回顾3 优秀参考图书推荐《信息学奥赛一本通关》4 高质量技术圈开放 1 信息学奥赛简介 信息学奥赛,作为全国中学生学科奥林匹克“五大学科竞赛”之一…...
Python 进程池Pool Queue,运行不出来结果!
文章目录 代码及结论 代码及结论 import os from multiprocessing import Pool, Queue from collections import Counterdef func(q):q.put(1)queue Queue()with Pool(4) as pool:for i in range(10):pool.apply_async(func, args(queue,),)print(queue.qsize())上边的代码qu…...

yolov8实战第二天——yolov8训练结果分析(保姆式解读)
yolov8实战第一天——yolov8部署并训练自己的数据集(保姆式教程)-CSDN博客 我们在上一篇文章训练了一个老鼠的yolov8检测模型,训练结果如下图,接下来我们就详细解析下面几张图。 一、混淆矩阵 正确挑选(正确&#…...
urllib.request --- 用于打开 URL 的可扩展库
源码: Lib/urllib/request.py urllib.request 模块定义了适用于在各种复杂情况下打开 URL(主要为 HTTP)的函数和类 --- 例如基本认证、摘要认证、重定向、cookies 及其它。 参见 对于更高级别的 HTTP 客户端接口,建议使用 Reques…...

【Docker】进阶之路:(十二)Docker Composer
【Docker】进阶之路:(十二)Docker Composer Docker Compose 简介安装 Docker Compose模板文件语法docker-compose.yml 语法说明imagecommandlinksexternal_linksportsexposevolumesvolunes_fromenvironmentenv_fileextendsnetpiddnscap_add,c…...

MES安灯管理:优化生产监控的重要工具
一、MES安灯管理的概念 MES安灯管理是一种基于物理安灯和数字化管理的生产异常管理工具。它通过物理安灯和数字化系统的结合,实现对生产异常的实时监控和及时反馈,从而帮助企业快速响应和解决生产异常,提高生产效率和产品质量。 二、MES系统…...

Unity中URP Shader 的 SRP Batcher
文章目录 前言一、SRP Batcher是什么二、SRP Batcher的使用条件1、可编程渲染管线2、我们用URP作为例子3、URP 设置中 Use SRP Batcher开启4、使 SRP Batcher 代码路径能够渲染对象5、使着色器与 SRP Batcher 兼容: 三、不同合批之间的区别BuildIn Render Pipeline下…...

十四 动手学深度学习v2计算机视觉 ——转置矩阵
文章目录 基本操作填充、步幅和多通道再谈转置卷积不填充,步幅为1填充为p,步幅为1填充为p,步幅为s 基本操作 填充、步幅和多通道 填充: 与常规卷积不同,在转置卷积中,填充被应用于的输出(常规卷…...
Spark-Streaming+Kafka+mysql实战示例
文章目录 前言一、简介1. Spark-Streaming简介2. Kafka简介二、实战演练1. MySQL数据库部分2. 导入依赖3. 编写实体类代码4. 编写kafka主题管理代码5. 编写kafka生产者代码6. 编写Spark-Streaming代码7. 查看数据库8. 代码下载总结前言 本文将介绍一个使用Spark Streaming和Ka…...
C++改写为C
stm使用中,经常能见到CPP的示例,这些是给arduino,esp32用的,stm32 也支持cpp但是你就想用c怎么办呢,比如我在新手的时候:: 这个双冒号就难住了英雄好汉 比如这是个cpp的 如果类不多的情况下 改写…...

抖去推--短视频剪辑、矩阵无人直播saas营销工具一站式开发
抖去推是一款短视频剪辑和矩阵无人直播SAAS营销工具一站式开发平台。它提供了以下功能和特点: 1. 短视频剪辑:抖去推提供了一系列的剪辑工具,包括自动剪辑、特效制作、配音配乐等,可以帮助用户轻松制作出高质量的短视频。 2. 矩阵…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
高防服务器能够抵御哪些网络攻击呢?
高防服务器作为一种有着高度防御能力的服务器,可以帮助网站应对分布式拒绝服务攻击,有效识别和清理一些恶意的网络流量,为用户提供安全且稳定的网络环境,那么,高防服务器一般都可以抵御哪些网络攻击呢?下面…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
虚拟电厂发展三大趋势:市场化、技术主导、车网互联
市场化:从政策驱动到多元盈利 政策全面赋能 2025年4月,国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》,首次明确虚拟电厂为“独立市场主体”,提出硬性目标:2027年全国调节能力≥2000万千瓦࿰…...