set -euo pipefail # 严格模式:遇到错误退出,未定义变量报错
SCRIPT_NAME=$(basename "$0")
SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
LOG_FILE="/var/log/${SCRIPT_NAME%.*}.log"
COMPOSE_VERSION="2.27.1" # 使用更新的稳定版本
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 日志函数
log() {
local level=$1
shift
local message="$*"
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo -e "${timestamp} [${level}] ${message}" | tee -a "$LOG_FILE"
}
log_info() { log "INFO" "$@"; }
log_warn() { log "WARN" "${YELLOW}$@${NC}"; }
log_error() { log "ERROR" "${RED}$@${NC}"; }
log_success() { log "SUCCESS" "${GREEN}$@${NC}"; }
# 通用Shell函数库
# 描述: 包含脚本开发中最常用的函数集合
# 设置严格模式
set -euo pipefail
# 颜色定义
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[0;33m'
readonly BLUE='\033[0;34m'
readonly PURPLE='\033[0;35m'
readonly CYAN='\033[0;36m'
readonly WHITE='\033[0;37m'
readonly NC='\033[0m' # No Color
# 日志级别定义
readonly LOG_LEVEL_DEBUG=0
readonly LOG_LEVEL_INFO=1
readonly LOG_LEVEL_WARN=2
readonly LOG_LEVEL_ERROR=3
readonly LOG_LEVEL_FATAL=4
# 全局变量
SCRIPT_NAME=$(basename "$0")
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
LOG_LEVEL=${LOG_LEVEL:-1}
LOG_FILE="${LOG_FILE:-/tmp/${SCRIPT_NAME%.*}.log}"
#==============================================================================
# 日志记录函数
#==============================================================================
# 打印调试信息
log_debug() {
if [[ $LOG_LEVEL -le $LOG_LEVEL_DEBUG ]]; then
echo -e "${CYAN}[DEBUG]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE"
fi
}
# 打印普通信息
log_info() {
if [[ $LOG_LEVEL -le $LOG_LEVEL_INFO ]]; then
echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE"
fi
}
# 打印警告信息
log_warn() {
if [[ $LOG_LEVEL -le $LOG_LEVEL_WARN ]]; then
echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE"
fi
}
# 打印错误信息
log_error() {
if [[ $LOG_LEVEL -le $LOG_LEVEL_ERROR ]]; then
echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE"
fi
}
# 打印致命错误并退出
log_fatal() {
if [[ $LOG_LEVEL -le $LOG_LEVEL_FATAL ]]; then
echo -e "${RED}[FATAL]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $*" | tee -a "$LOG_FILE"
fi
exit 1
}
#==============================================================================
# 文件操作函数
#==============================================================================
# 检查文件是否存在
file_exists() {
[[ -f "$1" ]]
}
# 检查目录是否存在
dir_exists() {
[[ -d "$1" ]]
}
# 创建目录(如果不存在)
ensure_dir() {
local dir="$1"
if [[ ! -d "$dir" ]]; then
mkdir -p "$dir"
log_info "创建目录: $dir"
fi
}
# 安全删除文件
safe_rm() {
local file="$1"
if file_exists "$file"; then
rm -f "$file"
log_info "删除文件: $file"
fi
}
# 备份文件
backup_file() {
local src="$1"
local backup="${src}.backup.$(date +%Y%m%d_%H%M%S)"
if file_exists "$src"; then
cp "$src" "$backup"
log_info "备份文件: $src -> $backup"
echo "$backup"
else
log_error "源文件不存在: $src"
return 1
fi
}
# 获取文件大小(人类可读格式)
get_file_size() {
local file="$1"
if file_exists "$file"; then
du -h "$file" | cut -f1
else
echo "0"
fi
}
# 查找文件
find_files() {
local pattern="$1"
local dir="${2:-.}"
find "$dir" -type f -name "$pattern" 2>/dev/null
}
#==============================================================================
# 字符串处理函数
#==============================================================================
# 字符串转小写
to_lower() {
echo "$1" | tr '[:upper:]' '[:lower:]'
}
# 字符串转大写
to_upper() {
echo "$1" | tr '[:lower:]' '[:upper:]'
}
# 去除字符串首尾空格
trim() {
local str="$1"
str="${str#"${str%%[![:space:]]*}"}"
str="${str%"${str##*[![:space:]]}"}"
echo "$str"
}
# 检查字符串是否为空
is_empty() {
[[ -z "${1:-}" ]]
}
# 检查字符串是否包含子串
contains() {
local str="$1"
local substr="$2"
[[ "$str" == *"$substr"* ]]
}
# 检查字符串是否以指定前缀开始
starts_with() {
local str="$1"
local prefix="$2"
[[ "$str" == "$prefix"* ]]
}
# 检查字符串是否以指定后缀结束
ends_with() {
local str="$1"
local suffix="$2"
[[ "$str" == *"$suffix" ]]
}
# 替换字符串中的子串
replace_str() {
local str="$1"
local old="$2"
local new="$3"
echo "${str//$old/$new}"
}
#==============================================================================
# 网络检查函数
#==============================================================================
# 检查网络连接
check_network() {
local host="${1:-8.8.8.8}"
local timeout="${2:-3}"
if ping -c 1 -W "$timeout" "$host" >/dev/null 2>&1; then
log_info "网络连接正常"
return 0
else
log_error "网络连接失败"
return 1
fi
}
# 检查URL是否可访问
check_url() {
local url="$1"
local timeout="${2:-10}"
if command -v curl >/dev/null 2>&1; then
if curl -s --max-time "$timeout" --head "$url" | head -n 1 | grep -q "200\|301\|302"; then
log_info "URL可访问: $url"
return 0
else
log_error "URL不可访问: $url"
return 1
fi
else
log_error "curl命令未找到"
return 1
fi
}
# 获取本机IP地址
get_local_ip() {
local ip
if command -v ip >/dev/null 2>&1; then
ip=$(ip route get 1 2>/dev/null | awk '{print $7}' | head -1)
elif command -v ifconfig >/dev/null 2>&1; then
ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -1)
else
ip="127.0.0.1"
fi
echo "$ip"
}
#==============================================================================
# 系统信息函数
#==============================================================================
# 获取操作系统信息
get_os_info() {
if [[ -f /etc/os-release ]]; then
. /etc/os-release
echo "$NAME $VERSION"
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo "macOS $(sw_vers -productVersion)"
else
echo "Unknown OS"
fi
}
# 获取CPU信息
get_cpu_info() {
if [[ "$OSTYPE" == "darwin"* ]]; then
sysctl -n machdep.cpu.brand_string
else
grep -m1 "model name" /proc/cpuinfo | cut -d':' -f2 | sed 's/^ *//'
fi
}
# 获取内存信息
get_memory_info() {
if [[ "$OSTYPE" == "darwin"* ]]; then
local mem_bytes=$(sysctl -n hw.memsize)
echo "$((mem_bytes / 1024 / 1024 / 1024))GB"
else
free -h | awk '/^Mem:/ {print $2}'
fi
}
# 检查命令是否存在
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# 获取当前用户信息
get_user_info() {
echo "用户: $(whoami)"
echo "主机: $(hostname)"
echo "家目录: $HOME"
echo "Shell: $SHELL"
}
#==============================================================================
# 错误处理函数
#==============================================================================
# 错误处理
handle_error() {
local exit_code=$?
local line_number=$1
log_error "脚本执行失败,退出码: $exit_code,行号: $line_number"
exit $exit_code
}
# 设置错误陷阱
setup_error_handling() {
trap 'handle_error $LINENO' ERR
}
# 检查依赖命令
check_dependencies() {
local missing_deps=()
for cmd in "$@"; do
if ! command_exists "$cmd"; then
missing_deps+=("$cmd")
fi
done
if [[ ${#missing_deps[@]} -gt 0 ]]; then
log_error "缺少依赖命令: ${missing_deps[*]}"
return 1
fi
return 0
}
#==============================================================================
# 进度显示函数
#==============================================================================
# 显示进度条
show_progress() {
local current=$1
local total=$2
local width=50
local percentage=$((current * 100 / total))
local filled=$((width * current / total))
local empty=$((width - filled))
printf "\r["
printf "%${filled}s" | tr ' ' '='
printf "%${empty}s" | tr ' ' ' '
printf "] %d%%" "$percentage"
if [[ $current -eq $total ]]; then
echo
fi
}
# 显示旋转进度
show_spinner() {
local pid=$1
local delay=0.1
local spinstr='|/-\'
while kill -0 "$pid" 2>/dev/null; do
local temp=${spinstr#?}
printf " [%c] " "$spinstr"
local spinstr=$temp${spinstr%"$temp"}
sleep $delay
printf "\b\b\b\b\b\b"
done
printf " \b\b\b\b"
}
#==============================================================================
# 用户交互函数
#==============================================================================
# 确认提示
confirm() {
local message="${1:-是否继续执行?}"
local response
while true; do
echo -n "$message [y/N]: "
read -r response
case $response in
[yY][eE][sS]|[yY])
return 0
;;
[nN][oO]|[nN]|"")
return 1
;;
*)
echo "请输入 y 或 n"
;;
esac
done
}
# 输入提示
prompt_input() {
local prompt="$1"
local default="${2:-}"
local input
if [[ -n "$default" ]]; then
echo -n "$prompt [$default]: "
else
echo -n "$prompt: "
fi
read -r input
if [[ -z "$input" && -n "$default" ]]; then
echo "$default"
else
echo "$input"
fi
}
# 选择菜单
show_menu() {
local title="$1"
shift
local options=("$@")
echo
echo "=== $title ==="
for i in "${!options[@]}"; do
echo "$((i+1)). ${options[$i]}"
done
echo
local choice
while true; do
echo -n "请选择 [1-${#options[@]}]: "
read -r choice
if [[ "$choice" =~ ^[0-9]+$ ]] && [[ $choice -ge 1 ]] && [[ $choice -le ${#options[@]} ]]; then
echo $((choice-1))
return 0
else
echo "无效选择,请重试"
fi
done
}
#==============================================================================
# 时间日期函数
#==============================================================================
# 获取当前时间戳
get_timestamp() {
date +%s
}
# 获取格式化日期
get_date() {
local format="${1:-%Y-%m-%d %H:%M:%S}"
date "+$format"
}
# 计算时间差
time_diff() {
local start=$1
local end=$2
echo $((end - start))
}
#==============================================================================
# 数学计算函数
#==============================================================================
# 检查是否为数字
is_number() {
[[ "$1" =~ ^-?[0-9]+([.][0-9]+)?$ ]]
}
# 比较数字
compare_numbers() {
local op="$1"
local n1="$2"
local n2="$3"
case "$op" in
"eq") [[ "$n1" == "$n2" ]] ;;
"ne") [[ "$n1" != "$n2" ]] ;;
"gt") [[ $(echo "$n1 > $n2" | bc -l) == 1 ]] ;;
"lt") [[ $(echo "$n1 < $n2" | bc -l) == 1 ]] ;;
"ge") [[ $(echo "$n1 >= $n2" | bc -l) == 1 ]] ;;
"le") [[ $(echo "$n1 <= $n2" | bc -l) == 1 ]] ;;
*) return 1 ;;
esac
}
#==============================================================================
# 初始化函数
#==============================================================================
# 初始化脚本环境
init_script() {
setup_error_handling
# 确保日志目录存在
ensure_dir "$(dirname "$LOG_FILE")"
log_info "脚本初始化完成"
log_info "脚本名称: $SCRIPT_NAME"
log_info "脚本目录: $SCRIPT_DIR"
log_info "日志文件: $LOG_FILE"
log_info "操作系统: $(get_os_info)"
}
#==============================================================================
# 使用示例
#==============================================================================
# 使用示例函数
show_usage_example() {
cat << EOF
使用示例:
# 1. 引入函数库
source common_functions.sh
# 2. 初始化
init_script
# 3. 使用日志函数
log_info "这是一条信息"
log_error "这是一条错误"
# 4. 文件操作
if file_exists "/etc/passwd"; then
log_info "文件存在"
fi
# 5. 网络检查
if check_network; then
log_info "网络正常"
fi
# 6. 用户交互
if confirm "是否继续?"; then
log_info "用户选择了继续"
fi
# 7. 进度显示
for i in {1..10}; do
show_progress $i 10
sleep 0.5
done
EOF
}
# 如果直接运行此脚本,显示使用示例
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
show_usage_example
fi
readonly SCRIPT_NAME=$(basename "$0")
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >&2
}
# 错误处理函数
error_exit() {
log "错误: $1"
exit 1
}
==================================================================
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 带颜色和时间的调试函数
debug() {
echo -e "${BLUE}[DEBUG $(date '+%Y-%m-%d %H:%M:%S')]${NC} $*" >&2
}
info() {
echo -e "${GREEN}[INFO $(date '+%Y-%m-%d %H:%M:%S')]${NC} $*" >&2
}
warn() {
echo -e "${YELLOW}[WARN $(date '+%Y-%m-%d %H:%M:%S')]${NC} $*" >&2
}
error() {
echo -e "${RED}[ERROR $(date '+%Y-%m-%d %H:%M:%S')]${NC} $*" >&2
exit 1
}
函数库高级版本
#!/bin/bash
# 高级Shell函数库
# 日期: 2025-12-12
# 描述: 包含高级功能的函数集合,如JSON处理、配置管理、加密解密等
# 设置严格模式
set -euo pipefail
# 引入基础函数库
if [[ -f "$(dirname "${BASH_SOURCE[0]}")/common_functions.sh" ]]; then
source "$(dirname "${BASH_SOURCE[0]}")/common_functions.sh"
fi
#==============================================================================
# JSON处理函数
#==============================================================================
# 检查JSON格式是否有效
is_valid_json() {
local json="$1"
if command -v jq >/dev/null 2>&1; then
echo "$json" | jq . >/dev/null 2>&1
elif command -v python3 >/dev/null 2>&1; then
python3 -c "import json; json.loads('$json')" >/dev/null 2>&1
else
log_error "未找到JSON解析工具 (jq 或 python3)"
return 1
fi
}
# 从JSON中获取值
get_json_value() {
local json="$1"
local key="$2"
if command -v jq >/dev/null 2>&1; then
echo "$json" | jq -r ".$key // empty" 2>/dev/null
elif command -v python3 >/dev/null 2>&1; then
python3 -c "import json; data = json.loads('$json'); print(data.get('$key', ''))" 2>/dev/null
else
log_error "未找到JSON解析工具"
return 1
fi
}
# 设置JSON值
set_json_value() {
local json="$1"
local key="$2"
local value="$3"
if command -v jq >/dev/null 2>&1; then
echo "$json" | jq ".$key = \"$value\"" 2>/dev/null
else
log_error "需要安装jq工具"
return 1
fi
}
# 合并两个JSON对象
merge_json() {
local json1="$1"
local json2="$2"
if command -v jq >/dev/null 2>&1; then
echo "$json1" "$json2" | jq -s '.[0] * .[1]' 2>/dev/null
else
log_error "需要安装jq工具"
return 1
fi
}
#==============================================================================
# 配置文件处理函数
#==============================================================================
# 读取INI配置文件
read_ini_config() {
local file="$1"
local section="$2"
local key="$3"
if [[ ! -f "$file" ]]; then
log_error "配置文件不存在: $file"
return 1
fi
local value
value=$(awk -F '=' -v section="[$section]" -v key="$key" '
$0 == section { found=1; next }
found && /^\[/ { exit }
found && $1 ~ "^ *"key" *" { gsub(/^[ \t]+|[ \t]+$/, "", $2); print $2; exit }
' "$file")
echo "$value"
}
# 写入INI配置文件
write_ini_config() {
local file="$1"
local section="$2"
local key="$3"
local value="$4"
ensure_dir "$(dirname "$file")"
if [[ ! -f "$file" ]]; then
echo "[$section]" > "$file"
echo "$key=$value" >> "$file"
log_info "创建配置文件: $file"
else
# 使用sed更新或添加配置
if grep -q "^\[$section\]" "$file"; then
if grep -A 20 "^\[$section\]" "$file" | grep -q "^$key="; then
sed -i "/^\[$section\]/,/^$/ s/^$key=.*/$key=$value/" "$file"
else
sed -i "/^\[$section\]/a $key=$value" "$file"
fi
else
echo "" >> "$file"
echo "[$section]" >> "$file"
echo "$key=$value" >> "$file"
fi
log_info "更新配置: [$section] $key=$value"
fi
}
# 读取YAML配置(简单实现)
read_yaml_config() {
local file="$1"
local key="$2"
if [[ ! -f "$file" ]]; then
log_error "YAML文件不存在: $file"
return 1
fi
if command -v yq >/dev/null 2>&1; then
yq eval ".$key" "$file" 2>/dev/null
else
# 简单的YAML解析
grep "^$key:" "$file" | head -1 | cut -d':' -f2- | sed 's/^[ \t]*//'
fi
}
#==============================================================================
# 加密解密函数
#==============================================================================
# Base64编码
base64_encode() {
local text="$1"
if command -v base64 >/dev/null 2>&1; then
echo -n "$text" | base64
else
log_error "base64命令未找到"
return 1
fi
}
# Base64解码
base64_decode() {
local encoded="$1"
if command -v base64 >/dev/null 2>&1; then
echo -n "$encoded" | base64 -d
else
log_error "base64命令未找到"
return 1
fi
}
# MD5哈希
md5_hash() {
local text="$1"
if command -v md5sum >/dev/null 2>&1; then
echo -n "$text" | md5sum | cut -d' ' -f1
elif command -v md5 >/dev/null 2>&1; then
echo -n "$text" | md5
else
log_error "未找到MD5工具"
return 1
fi
}
# SHA256哈希
sha256_hash() {
local text="$1"
if command -v sha256sum >/dev/null 2>&1; then
echo -n "$text" | sha256sum | cut -d' ' -f1
elif command -v shasum >/dev/null 2>&1; then
echo -n "$text" | shasum -a 256 | cut -d' ' -f1
else
log_error "未找到SHA256工具"
return 1
fi
}
# 生成随机字符串
generate_random_string() {
local length="${1:-16}"
local chars="A-Za-z0-9"
if command -v openssl >/dev/null 2>&1; then
openssl rand -base64 "$length" | tr -d "=+/" | cut -c1-"$length"
elif command -v tr >/dev/null 2>&1; then
tr -dc "$chars" </dev/urandom | head -c "$length"
else
date | md5sum | head -c "$length"
fi
}
#==============================================================================
# 数据验证函数
#==============================================================================
# 验证邮箱格式
is_valid_email() {
local email="$1"
[[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]
}
# 验证手机号(中国)
is_valid_phone() {
local phone="$1"
[[ "$phone" =~ ^1[3-9][0-9]{9}$ ]]
}
# 验证IP地址
is_valid_ip() {
local ip="$1"
local regex='^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
[[ "$ip" =~ $regex ]]
}
# 验证URL
is_valid_url() {
local url="$1"
local regex='^(https?|ftp)://[^\s/$.?#].[^\s]*$'
[[ "$url" =~ $regex ]]
}
# 验证端口号
is_valid_port() {
local port="$1"
[[ "$port" =~ ^[0-9]+$ ]] && [[ $port -ge 1 ]] && [[ $port -le 65535 ]]
}
#==============================================================================
# 系统高级功能函数
#==============================================================================
# 获取进程PID
get_process_pid() {
local process_name="$1"
pgrep -f "$process_name" 2>/dev/null || echo ""
}
# 检查进程是否在运行
is_process_running() {
local process_name="$1"
pgrep -f "$process_name" >/dev/null 2>&1
}
# 安全杀死进程
safe_kill_process() {
local process_name="$1"
local signal="${2:-TERM}"
local pids
pids=$(get_process_pid "$process_name")
if [[ -n "$pids" ]]; then
log_info "正在终止进程: $process_name (PID: $pids)"
kill -"$signal" $pids 2>/dev/null
# 等待进程结束
local count=0
while is_process_running "$process_name" && [[ $count -lt 10 ]]; do
sleep 1
((count++))
done
if is_process_running "$process_name"; then
log_warn "进程仍在运行,可能需要强制终止"
return 1
else
log_info "进程已成功终止"
return 0
fi
else
log_warn "未找到进程: $process_name"
return 1
fi
}
# 获取系统负载
get_system_load() {
if [[ "$OSTYPE" == "darwin"* ]]; then
uptime | awk '{print $(NF-2)}' | sed 's/,//'
else
uptime | awk -F'load average:' '{print $2}' | awk '{print $1}' | sed 's/,//'
fi
}
# 获取磁盘使用率
get_disk_usage() {
local path="${1:-/}"
df -h "$path" | awk 'NR==2 {print $5}' | sed 's/%//'
}
# 获取内存使用率
get_memory_usage() {
if [[ "$OSTYPE" == "darwin"* ]]; then
vm_stat | awk '/Pages active/ {active=$3} /Pages inactive/ {inactive=$3} /Pages wired/ {wired=$3} /Pages free/ {free=$3} END {total=active+inactive+wired+free; used=active+inactive+wired; print int(used/total*100)}' | sed 's/[^0-9]//g'
else
free | awk '/Mem:/ {printf("%.0f", $3/$2*100)}'
fi
}
#==============================================================================
# 备份恢复函数
#==============================================================================
# 创建压缩备份
create_backup() {
local source="$1"
local backup_dir="${2:-./backups}"
local backup_name="${3:-backup_$(date +%Y%m%d_%H%M%S)}"
ensure_dir "$backup_dir"
if [[ -d "$source" ]]; then
local backup_file="$backup_dir/${backup_name}.tar.gz"
tar -czf "$backup_file" -C "$(dirname "$source")" "$(basename "$source")" 2>/dev/null
log_info "目录备份完成: $source -> $backup_file"
echo "$backup_file"
elif [[ -f "$source" ]]; then
local backup_file="$backup_dir/${backup_name}.gz"
gzip -c "$source" > "$backup_file"
log_info "文件备份完成: $source -> $backup_file"
echo "$backup_file"
else
log_error "备份源不存在: $source"
return 1
fi
}
# 恢复备份
restore_backup() {
local backup_file="$1"
local target_dir="${2:-.}"
if [[ ! -f "$backup_file" ]]; then
log_error "备份文件不存在: $backup_file"
return 1
fi
ensure_dir "$target_dir"
if [[ "$backup_file" == *.tar.gz ]]; then
tar -xzf "$backup_file" -C "$target_dir"
log_info "备份恢复完成: $backup_file -> $target_dir"
elif [[ "$backup_file" == *.gz ]]; then
local filename=$(basename "$backup_file" .gz)
gzip -dc "$backup_file" > "$target_dir/$filename"
log_info "文件恢复完成: $backup_file -> $target_dir/$filename"
else
log_error "不支持的备份文件格式: $backup_file"
return 1
fi
}
#==============================================================================
# 使用示例
#==============================================================================
# 显示使用示例
show_advanced_usage_example() {
cat << EOF
高级函数库使用示例:
# 1. 引入函数库
source advanced_functions.sh
# 2. JSON处理
json_data='{"name": "John", "age": 30}'
if is_valid_json "$json_data"; then
name=$(get_json_value "$json_data" "name")
log_info "姓名: $name"
fi
# 3. 配置文件操作
write_ini_config "app.conf" "database" "host" "localhost"
db_host=$(read_ini_config "app.conf" "database" "host")
log_info "数据库主机: $db_host"
# 4. 数据验证
email="test@example.com"
if is_valid_email "$email"; then
log_info "邮箱格式正确"
fi
# 5. 加密解密
password="secret123"
encoded=$(base64_encode "$password")
decoded=$(base64_decode "$encoded")
log_info "原始: $password, 编码: $encoded, 解码: $decoded"
# 6. 系统监控
load=$(get_system_load)
memory=$(get_memory_usage)
log_info "系统负载: $load, 内存使用率: ${memory}%"
# 7. 备份恢复
backup_file=$(create_backup "/important/data")
log_info "备份文件: $backup_file"
# 8. 进程管理
if is_process_running "nginx"; then
log_info "Nginx正在运行"
fi
EOF
}
# 如果直接运行此脚本,显示使用示例
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
show_advanced_usage_example
fi
TIME-WAIT 状态监控脚本
#!/bin/bash
# TIME-WAIT 状态监控脚本
monitor_timewait() {
echo "=== TIME-WAIT 连接统计 ==="
ss -ant | awk '
NR>1 {states[$1]++}
END {
printf "%-12s %-8s\n", "状态", "数量"
printf "%-12s %-8s\n", "------", "------"
for (state in states) {
printf "%-12s %-8s\n", state, states[state]
}
}'
echo -e "\n=== 详细的 TIME-WAIT 连接 ==="
ss -ant state time-wait | head -20
echo -e "\n=== 内核参数检查 ==="
sysctl -a 2>/dev/null | grep -E "(tw_reuse|tw_recycle|fin_timeout|max_tw_buckets)" | grep -v "net.ipv6"
}
# 持续监控
continuous_monitor() {
while true; do
clear
monitor_timewait
echo -e "\n按 Ctrl+C 退出监控"
sleep 5
done
}
# 检查特定端口的 TIME-WAIT
check_port_timewait() {
local port=${1:-80}
echo "=== 端口 $port 的 TIME-WAIT 连接 ==="
ss -ant sport = :$port state time-wait
echo -e "\n总数: $(ss -ant sport = :$port state time-wait | wc -l)"
}
case "${1:-monitor}" in
"monitor")
monitor_timewait
;;
"continuous")
continuous_monitor
;;
"port")
check_port_timewait "$2"
;;
*)
echo "用法: $0 [monitor|continuous|port PORT]"
;;
esac
优化脚本
#!/bin/bash
# TIME-WAIT 自动优化脚本
apply_optimizations() {
local level="${1:-medium}"
case "$level" in
"light")
# 轻度优化
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
sudo sysctl -w net.ipv4.tcp_fin_timeout=45
;;
"medium")
# 中度优化
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
sudo sysctl -w net.ipv4.tcp_fin_timeout=30
sudo sysctl -w net.ipv4.tcp_max_tw_buckets=180000
sudo sysctl -w net.ipv4.ip_local_port_range="10000 65535"
;;
"aggressive")
# 激进优化
sudo sysctl -w net.ipv4.tcp_tw_reuse=1
sudo sysctl -w net.ipv4.tcp_tw_recycle=1
sudo sysctl -w net.ipv4.tcp_fin_timeout=15
sudo sysctl -w net.ipv4.tcp_max_tw_buckets=100000
sudo sysctl -w net.ipv4.ip_local_port_range="15000 65535"
;;
esac
echo "已应用 $level 级别的优化"
}
# 备份当前配置
backup_config() {
local backup_file="/tmp/sysctl_backup_$(date +%Y%m%d_%H%M%S).conf"
sysctl -a 2>/dev/null | grep -E "(tw_reuse|tw_recycle|fin_timeout|max_tw_buckets|ip_local_port_range)" > "$backup_file"
echo "配置已备份到: $backup_file"
}
# 恢复配置
restore_config() {
local backup_file="$1"
if [[ -f "$backup_file" ]]; then
while IFS= read -r line; do
if [[ "$line" =~ ^[a-z] ]]; then
local key=$(echo "$line" | cut -d'=' -f1 | awk '{print $1}')
local value=$(echo "$line" | cut -d'=' -f2 | awk '{print $1}')
sudo sysctl -w "$key=$value"
fi
done < "$backup_file"
echo "配置已从 $backup_file 恢复"
else
echo "备份文件不存在: $backup_file"
fi
}
case "${1:-help}" in
"apply")
apply_optimizations "$2"
;;
"backup")
backup_config
;;
"restore")
restore_config "$2"
;;
*)
echo "用法: $0 [apply LEVEL|backup|restore FILE]"
echo "LEVEL: light|medium|aggressive"
;;
esac
日期函数
#!/bin/bash
#===============================================================================
# Shell日期处理函数库
# 描述: 提供各种日期相关的实用函数和组合方法
# 版本: 1.0
#===============================================================================
# 设置错误处理
set -euo pipefail
#===============================================================================
# 基础配置和检查
#===============================================================================
# 检查系统类型和命令可用性
check_date_commands() {
local commands=("date" "cal" "seq" "awk" "sed")
local missing=()
for cmd in "${commands[@]}"; do
if ! command -v "$cmd" &> /dev/null; then
missing+=("$cmd")
fi
done
if [ ${#missing[@]} -ne 0 ]; then
echo "警告: 缺少以下命令: ${missing[*]}"
echo "某些功能可能无法使用"
fi
}
#===============================================================================
# 基础日期获取函数
#===============================================================================
# 获取当前日期的各种格式
get_current_date_formats() {
echo "=== 当前日期格式示例 ==="
# ISO格式 (YYYY-MM-DD)
echo "ISO格式: $(date '+%Y-%m-%d')"
# 美式格式 (MM/DD/YYYY)
echo "美式格式: $(date '+%m/%d/%Y')"
# 欧式格式 (DD/MM/YYYY)
echo "欧式格式: $(date '+%d/%m/%Y')"
# 中文格式 (YYYY年MM月DD日)
echo "中文格式: $(date '+%Y年%m月%d日')"
# 时间戳 (秒)
echo "Unix时间戳: $(date '+%s')"
# 时间戳 (毫秒)
echo "毫秒时间戳: $(date '+%s%3N')"
# 带时间的完整格式
echo "完整日期时间: $(date '+%Y-%m-%d %H:%M:%S')"
# RFC 2822格式
echo "RFC 2822格式: $(date '+%a, %d %b %Y %H:%M:%S %z')"
# 自定义格式
echo "自定义格式1: $(date '+%Y%m%d_%H%M%S')"
echo "自定义格式2: $(date '+%d-%b-%Y')"
echo "自定义格式3: $(date '+%A, %B %d, %Y')"
}
#===============================================================================
# 日期计算函数
#===============================================================================
# 日期加减计算
date_calculate() {
local base_date="${1:-$(date '+%Y-%m-%d')}"
local operation="${2:-+}" # + 或 -
local days="${3:-1}"
if [[ "$operation" == "+" ]]; then
date -d "$base_date + $days days" '+%Y-%m-%d'
else
date -d "$base_date - $days days" '+%Y-%m-%d'
fi
}
# 月份加减计算
month_calculate() {
local base_date="${1:-$(date '+%Y-%m-%d')}"
local operation="${2:-+}"
local months="${3:-1}"
if [[ "$operation" == "+" ]]; then
date -d "$base_date + $months months" '+%Y-%m-%d'
else
date -d "$base_date - $months months" '+%Y-%m-%d'
fi
}
# 年份加减计算
year_calculate() {
local base_date="${1:-$(date '+%Y-%m-%d')}"
local operation="${2:-+}"
local years="${3:-1}"
if [[ "$operation" == "+" ]]; then
date -d "$base_date + $years years" '+%Y-%m-%d'
else
date -d "$base_date - $years years" '+%Y-%m-%d'
fi
}
#===============================================================================
# 日期比较函数
#===============================================================================
# 比较两个日期
compare_dates() {
local date1="$1"
local date2="$2"
local timestamp1=$(date -d "$date1" '+%s')
local timestamp2=$(date -d "$date2" '+%s')
if [[ $timestamp1 -lt $timestamp2 ]]; then
echo "-1" # date1 < date2
elif [[ $timestamp1 -gt $timestamp2 ]]; then
echo "1" # date1 > date2
else
echo "0" # date1 = date2
fi
}
# 检查日期是否在范围内
is_date_in_range() {
local check_date="$1"
local start_date="$2"
local end_date="$3"
local check_ts=$(date -d "$check_date" '+%s')
local start_ts=$(date -d "$start_date" '+%s')
local end_ts=$(date -d "$end_date" '+%s')
if [[ $check_ts -ge $start_ts && $check_ts -le $end_ts ]]; then
echo "true"
else
echo "false"
fi
}
# 计算两个日期之间的天数
days_between() {
local date1="$1"
local date2="$2"
local ts1=$(date -d "$date1" '+%s')
local ts2=$(date -d "$date2" '+%s')
local diff=$(( (ts2 - ts1) / 86400 ))
echo ${diff#-} # 返回绝对值
}
#===============================================================================
# 日期格式转换函数
#===============================================================================
# 时间戳转日期
timestamp_to_date() {
local timestamp="$1"
local format="${2:-%Y-%m-%d %H:%M:%S}"
date -d "@$timestamp" "+$format"
}
# 日期转时间戳
date_to_timestamp() {
local date_str="$1"
date -d "$date_str" '+%s'
}
# 转换日期格式
convert_date_format() {
local date_str="$1"
local input_format="$2"
local output_format="$3"
# 先解析输入格式,再输出目标格式
case "$input_format" in
"iso"|"ISO")
date -d "$date_str" "+$output_format"
;;
"us"|"US")
# MM/DD/YYYY to target format
local month=$(echo "$date_str" | cut -d'/' -f1)
local day=$(echo "$date_str" | cut -d'/' -f2)
local year=$(echo "$date_str" | cut -d'/' -f3)
date -d "$year-$month-$day" "+$output_format"
;;
"eu"|"EU")
# DD/MM/YYYY to target format
local day=$(echo "$date_str" | cut -d'/' -f1)
local month=$(echo "$date_str" | cut -d'/' -f2)
local year=$(echo "$date_str" | cut -d'/' -f3)
date -d "$year-$month-$day" "+$output_format"
;;
*)
echo "不支持的输入格式: $input_format"
return 1
;;
esac
}
#===============================================================================
# 工作日计算函数
#===============================================================================
# 获取星期几 (1-7, 1=Monday)
get_weekday() {
local date_str="${1:-$(date '+%Y-%m-%d')}"
date -d "$date_str" '+%u'
}
# 获取星期几名称
get_weekday_name() {
local date_str="${1:-$(date '+%Y-%m-%d')}"
local locale="${2:-zh_CN}"
if [[ "$locale" == "en" ]]; then
date -d "$date_str" '+%A'
else
# 中文环境
local weekday_num=$(date -d "$date_str" '+%w')
local weekdays=("星期日" "星期一" "星期二" "星期三" "星期四" "星期五" "星期六")
echo "${weekdays[$weekday_num]}"
fi
}
# 检查是否为工作日 (周一到周五)
is_workday() {
local date_str="${1:-$(date '+%Y-%m-%d')}"
local weekday=$(date -d "$date_str" '+%u')
if [[ $weekday -le 5 ]]; then
echo "true"
else
echo "false"
fi
}
# 获取下一个工作日
next_workday() {
local date_str="${1:-$(date '+%Y-%m-%d')}"
local current_date="$date_str"
while true; do
current_date=$(date_calculate "$current_date" "+" 1)
if [[ $(is_workday "$current_date") == "true" ]]; then
echo "$current_date"
break
fi
done
}
#===============================================================================
# 月份和年份处理函数
#===============================================================================
# 获取月份天数
days_in_month() {
local year="$1"
local month="$2"
case "$month" in
1|3|5|7|8|10|12) echo "31" ;;
4|6|9|11) echo "30" ;;
2)
# 闰年判断
if [[ $((year % 4)) -eq 0 && ($((year % 100)) -ne 0 || $((year % 400)) -eq 0) ]]; then
echo "29"
else
echo "28"
fi
;;
*)
echo "无效的月份: $month"
return 1
;;
esac
}
# 获取季度
get_quarter() {
local month="${1:-$(date '+%m')}"
echo $(((10#$month - 1) / 3 + 1))
}
# 获取月份开始和结束日期
get_month_range() {
local year="$1"
local month="$2"
local start_date="${year}-${month}-01"
local end_day=$(days_in_month "$year" "$month")
local end_date="${year}-${month}-${end_day}"
echo "$start_date 到 $end_date"
}
#===============================================================================
# 高级日期组合函数
#===============================================================================
# 生成日期序列
generate_date_sequence() {
local start_date="$1"
local end_date="$2"
local step="${3:-1}" # 步长(天)
local current="$start_date"
while [[ $(compare_dates "$current" "$end_date") -le 0 ]]; do
echo "$current"
current=$(date_calculate "$current" "+" "$step")
done
}
# 获取指定月份的所有工作日
get_workdays_in_month() {
local year="$1"
local month="$2"
local start_date="${year}-${month}-01"
local end_day=$(days_in_month "$year" "$month")
local end_date="${year}-${month}-${end_day}"
generate_date_sequence "$start_date" "$end_date" | while read -r date; do
if [[ $(is_workday "$date") == "true" ]]; then
echo "$date"
fi
done
}
# 计算年龄
calculate_age() {
local birth_date="$1"
local current_date="${2:-$(date '+%Y-%m-%d')}"
local birth_ts=$(date_to_timestamp "$birth_date")
local current_ts=$(date_to_timestamp "$current_date")
local birth_year=$(date -d "$birth_date" '+%Y')
local current_year=$(date -d "$current_date" '+%Y')
local age=$((current_year - birth_year))
# 检查是否已经过了生日
local birth_month_day=$(date -d "$birth_date" '+%m%d')
local current_month_day=$(date -d "$current_date" '+%m%d')
if [[ "$current_month_day" < "$birth_month_day" ]]; then
age=$((age - 1))
fi
echo "$age"
}
#===============================================================================
# 实用工具函数
#===============================================================================
# 获取系统支持的日期格式
show_supported_formats() {
echo "=== 系统支持的日期格式 ==="
echo "标准格式: YYYY-MM-DD"
echo "美式格式: MM/DD/YYYY"
echo "欧式格式: DD/MM/YYYY"
echo "中文格式: YYYY年MM月DD日"
echo "紧凑格式: YYYYMMDD"
echo "时间戳格式: @timestamp"
}
# 演示所有功能
demo_all_functions() {
echo "=== 日期处理函数演示 ==="
# 基础日期格式
get_current_date_formats
echo
# 日期计算示例
echo "=== 日期计算示例 ==="
local today=$(date '+%Y-%m-%d')
echo "今天: $today"
echo "明天: $(date_calculate "$today" "+" 1)"
echo "昨天: $(date_calculate "$today" "-" 1)"
echo "一周后: $(date_calculate "$today" "+" 7)"
echo "一月后: $(month_calculate "$today" "+" 1)"
echo "一年后: $(year_calculate "$today" "+" 1)"
echo
# 日期比较示例
echo "=== 日期比较示例 ==="
local date1="2024-01-01"
local date2="2024-12-31"
echo "比较 $date1 和 $date2: $(compare_dates "$date1" "$date2")"
echo "$date1 到 $date2 的天数: $(days_between "$date1" "$date2")"
echo
# 工作日相关
echo "=== 工作日相关 ==="
echo "今天是工作日: $(is_workday)"
echo "今天是星期几: $(get_weekday_name)"
echo "下一个工作日: $(next_workday)"
echo
# 月份信息
echo "=== 月份信息 ==="
local current_year=$(date '+%Y')
local current_month=$(date '+%m')
echo "$current_year年$current_month月有 $(days_in_month "$current_year" "$current_month") 天"
echo "当前季度: 第$(get_quarter)季度"
echo "本月工作日: $(get_workdays_in_month "$current_year" "$current_month" | wc -l) 天"
}
#===============================================================================
# 帮助函数
#===============================================================================
show_help() {
cat << 'EOF'
日期处理函数库 - 使用帮助
基础函数:
get_current_date_formats - 显示各种日期格式
date_calculate <date> <+/-> <days> - 日期加减
month_calculate <date> <+/-> <months> - 月份加减
year_calculate <date> <+/-> <years> - 年份加减
比较函数:
compare_dates <date1> <date2> - 比较两个日期
is_date_in_range <date> <start> <end> - 检查日期是否在范围内
days_between <date1> <date2> - 计算日期间隔天数
转换函数:
timestamp_to_date <timestamp> [format] - 时间戳转日期
date_to_timestamp <date> - 日期转时间戳
convert_date_format <date> <input_fmt> <output_fmt> - 格式转换
工作日函数:
get_weekday [date] - 获取星期几(1-7)
get_weekday_name [date] [locale] - 获取星期几名称
is_workday [date] - 检查是否为工作日
next_workday [date] - 获取下一个工作日
月份函数:
days_in_month <year> <month> - 获取月份天数
get_quarter [month] - 获取季度
get_month_range <year> <month> - 获取月份开始结束日期
高级函数:
generate_date_sequence <start> <end> [step] - 生成日期序列
get_workdays_in_month <year> <month> - 获取月份所有工作日
calculate_age <birth_date> [current_date] - 计算年龄
工具函数:
show_supported_formats - 显示支持的格式
demo_all_functions - 演示所有功能
show_help - 显示此帮助
示例:
# 获取明天日期
date_calculate "" "+" 1
# 检查日期是否在工作范围内
is_date_in_range "2024-12-25" "2024-12-01" "2024-12-31"
# 计算年龄
calculate_age "1990-01-01"
# 获取工作日序列
get_workdays_in_month 2024 12
EOF
}
#===============================================================================
# 脚本入口点
#===============================================================================
main() {
case "${1:-help}" in
"demo")
demo_all_functions
;;
"formats")
show_supported_formats
;;
"check")
check_date_commands
;;
"help"|*)
show_help
;;
esac
}
# 如果直接执行脚本,则运行主函数
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。