Shell脚本如何实现动态配置

wen 实用脚本 2

本文目录导读:

Shell脚本如何实现动态配置

  1. 配置文件读取方式
  2. 命令行参数方式
  3. 环境变量方式
  4. JSON/YAML配置文件解析
  5. 动态配置管理函数
  6. 分层配置系统
  7. 实战示例:动态数据库配置
  8. 最佳实践建议

我来详细介绍Shell脚本实现动态配置的几种常用方法:

配置文件读取方式

使用source命令加载

#!/bin/bash
# config.conf 配置文件内容
# DB_HOST=localhost
# DB_PORT=3306
# DB_USER=root
# 加载配置
CONFIG_FILE="/path/to/config.conf"
if [ -f "$CONFIG_FILE" ]; then
    source "$CONFIG_FILE"
else
    echo "配置文件不存在,使用默认配置"
    DB_HOST="localhost"
    DB_PORT=3306
fi
echo "数据库主机: $DB_HOST"
echo "数据库端口: $DB_PORT"

使用sed解析配置

#!/bin/bash
# 从配置文件读取特定值
get_config() {
    local key=$1
    local config_file=$2
    grep "^${key}=" "$config_file" | cut -d'=' -f2
}
DB_HOST=$(get_config "DB_HOST" "/path/to/config.conf")
echo "数据库主机: $DB_HOST"

命令行参数方式

#!/bin/bash
# 使用getopts处理参数
usage() {
    echo "用法: $0 -h <主机> -p <端口> -u <用户>"
    exit 1
}
while getopts "h:p:u:" opt; do
    case $opt in
        h) DB_HOST="$OPTARG" ;;
        p) DB_PORT="$OPTARG" ;;
        u) DB_USER="$OPTARG" ;;
        *) usage ;;
    esac
done
# 设置默认值
DB_HOST=${DB_HOST:-"localhost"}
DB_PORT=${DB_PORT:-3306}
echo "连接配置: $DB_HOST:$DB_PORT"

环境变量方式

#!/bin/bash
# 设置默认值并支持环境变量覆盖
: ${APP_ENV:="development"}
: ${APP_DEBUG:="true"}
: ${APP_LOG_LEVEL:="info"}
echo "环境: $APP_ENV"
echo "调试模式: $APP_DEBUG"
# 检查必需的环境变量
check_env() {
    local required_vars=("DB_HOST" "DB_PASSWORD" "API_KEY")
    for var in "${required_vars[@]}"; do
        if [ -z "${!var}" ]; then
            echo "错误: 缺少必需的环境变量 $var"
            exit 1
        fi
    done
}

JSON/YAML配置文件解析

JSON解析(使用jq)

#!/bin/bash
# config.json 内容:
# {
#   "database": {
#     "host": "localhost",
#     "port": 3306
#   },
#   "debug": true
# }
if command -v jq &> /dev/null; then
    DB_HOST=$(jq -r '.database.host' config.json)
    DB_PORT=$(jq -r '.database.port' config.json)
    DEBUG=$(jq -r '.debug' config.json)
    echo "数据库配置: $DB_HOST:$DB_PORT"
else
    echo "请先安装jq工具"
    exit 1
fi

YAML解析(使用yq)

#!/bin/bash
# config.yaml 内容:
# database:
#   host: localhost
#   port: 3306
if command -v yq &> /dev/null; then
    DB_HOST=$(yq eval '.database.host' config.yaml)
    DB_PORT=$(yq eval '.database.port' config.yaml)
    echo "数据库配置: $DB_HOST:$DB_PORT"
fi

动态配置管理函数

#!/bin/bash
# 配置管理类函数
ConfigManager() {
    # 配置文件路径
    local CONFIG_FILE="/etc/myapp/config.conf"
    # 获取配置值
    get() {
        local key=$1
        local default=${2:-""}
        local value=$(grep "^${key}=" "$CONFIG_FILE" 2>/dev/null | cut -d'=' -f2)
        echo "${value:-$default}"
    }
    # 设置配置值
    set() {
        local key=$1
        local value=$2
        if grep -q "^${key}=" "$CONFIG_FILE" 2>/dev/null; then
            sed -i "s/^${key}=.*/${key}=${value}/" "$CONFIG_FILE"
        else
            echo "${key}=${value}" >> "$CONFIG_FILE"
        fi
    }
    # 列出所有配置
    list() {
        cat "$CONFIG_FILE" 2>/dev/null || echo "配置文件为空"
    }
}
# 使用示例
source ConfigManager
DB_HOST=$(get "DB_HOST" "localhost")
echo "当前数据库主机: $DB_HOST"
set "DB_PORT" "5432"
echo "数据库端口已更新"

分层配置系统

#!/bin/bash
# 支持多级配置覆盖
# 优先级: 命令行参数 > 环境变量 > 配置文件 > 默认值
# 默认配置
declare -A CONFIG=(
    ["DB_HOST"]="localhost"
    ["DB_PORT"]="3306"
    ["DB_USER"]="root"
    ["DEBUG"]="false"
)
# 加载配置文件
load_config_file() {
    local config_file=$1
    if [ -f "$config_file" ]; then
        while IFS='=' read -r key value; do
            # 跳过注释和空行
            [[ "$key" =~ ^#.*$ || -z "$key" ]] && continue
            CONFIG["$key"]="$value"
        done < "$config_file"
    fi
}
# 加载环境变量
load_env_vars() {
    for key in "${!CONFIG[@]}"; do
        env_var="APP_${key}"
        if [ -n "${!env_var}" ]; then
            CONFIG["$key"]="${!env_var}"
        fi
    done
}
# 加载命令行参数
load_cmd_args() {
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --db-host) CONFIG["DB_HOST"]="$2"; shift 2 ;;
            --db-port) CONFIG["DB_PORT"]="$2"; shift 2 ;;
            --debug) CONFIG["DEBUG"]="true"; shift ;;
            *) shift ;;
        esac
    done
}
# 使用配置
load_config_file "app.conf"
load_env_vars
load_cmd_args "$@"
echo "最终配置:"
for key in "${!CONFIG[@]}"; do
    echo "$key = ${CONFIG[$key]}"
done

实战示例:动态数据库配置

#!/bin/bash
# 数据库配置管理脚本
# 配置存储
CONFIG_FILE=".db_config"
declare -A DB_CONFIG
# 初始化配置
init_config() {
    cat > "$CONFIG_FILE" << EOF
# 数据库配置
DB_TYPE=mysql
DB_HOST=localhost
DB_PORT=3306
DB_NAME=test
DB_USER=root
DB_PASSWORD=
EOF
}
# 读取配置
read_config() {
    if [ ! -f "$CONFIG_FILE" ]; then
        echo "配置文件不存在,创建默认配置"
        init_config
    fi
    while IFS='=' read -r key value; do
        # 去除空格和注释
        key=$(echo "$key" | tr -d ' ' | grep -v '^#' )
        value=$(echo "$value" | tr -d ' ')
        if [ -n "$key" ] && [ -n "$value" ]; then
            DB_CONFIG["$key"]="$value"
        fi
    done < "$CONFIG_FILE"
}
# 动态更新配置
update_config() {
    local key=$1
    local value=$2
    DB_CONFIG["$key"]="$value"
    # 更新配置文件
    if grep -q "^${key}=" "$CONFIG_FILE"; then
        sed -i "s/^${key}=.*/${key}=${value}/" "$CONFIG_FILE"
    else
        echo "${key}=${value}" >> "$CONFIG_FILE"
    fi
}
# 生成数据库连接字符串
get_connection_string() {
    case ${DB_CONFIG["DB_TYPE"]} in
        mysql)
            echo "mysql://${DB_CONFIG["DB_USER"]}:${DB_CONFIG["DB_PASSWORD"]}@${DB_CONFIG["DB_HOST"]}:${DB_CONFIG["DB_PORT"]}/${DB_CONFIG["DB_NAME"]}"
            ;;
        postgresql)
            echo "postgresql://${DB_CONFIG["DB_USER"]}:${DB_CONFIG["DB_PASSWORD"]}@${DB_CONFIG["DB_HOST"]}:${DB_CONFIG["DB_PORT"]}/${DB_CONFIG["DB_NAME"]}"
            ;;
        *)
            echo "不支持的数据库类型"
            return 1
            ;;
    esac
}
# 主函数
main() {
    read_config
    # 处理命令行参数
    while [[ $# -gt 0 ]]; do
        case "$1" in
            --get-connection)
                get_connection_string
                ;;
            --update)
                shift
                update_config "$1" "$2"
                shift 2
                ;;
            --show)
                for key in "${!DB_CONFIG[@]}"; do
                    echo "$key = ${DB_CONFIG[$key]}"
                done
                ;;
            *)
                echo "未知参数: $1"
                exit 1
                ;;
        esac
    done
}
main "$@"

最佳实践建议

  1. 安全考虑

    • 敏感信息使用环境变量或加密存储
    • 配置文件权限设置为600
  2. 性能优化

    • 使用关联数组缓存配置
    • 避免频繁读写配置文件
  3. 灵活性

    • 支持多级配置覆盖
    • 提供配置校验和回滚机制
  4. 可维护性

    • 配置文���添加注释说明
    • 使用标准格式(如INI、YAML)

这些方法可以根据实际需求组合使用,实现灵活、安全的动态配置管理。

抱歉,评论功能暂时关闭!