Linux运维——Shell脚本读取配置文件

news2025/5/19 16:22:11

Shell脚本读取配置文件

  • 一、键值对格式配置文件(最常用)
    • 1.1、配置文件示例
    • 1.2、source命令导入
    • 1.3、sed解析
    • 1.4、解析数组
  • 二、INI格式配置文件
    • 1.1、配置文件示例
    • 1.2、sed解析
    • 1.3、ini配置带数组(显式声明数组)
    • 1.4、ini配置带数组(逗号分隔数组)
  • 三、Yaml格式配置文件
    • 3.1、配置文件示例
    • 3.2、安装yq工具
    • 3.3、使用yq工具解析
    • 3.4、使用python的PyYAML库
  • 四、JSON格式配置文件
    • 4.1、配置文件示例
    • 4.2、安装jq
    • 4.3、jq读取配置脚本
    • 4.4、Python的json模块解析
  • 五、环境变量文件(.env格式)
    • 5.1、配置文件示例
    • 5.2、source加载
    • 5.3、逐行解析(更安全)
    • 5.4、完整案例(生产级实现)

一、键值对格式配置文件(最常用)

1.1、配置文件示例

config.cfg

# 这是注释
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASS=password123
DEBUG_MODE=true

1.2、source命令导入

#!/bin/bash
# 直接source导入(简单但需确保配置文件安全)
source config.cfg

# 使用配置
echo "数据库主机: $DB_HOST"
echo "数据库端口: $DB_PORT"

直接使用source加载配置可能存在问题,更好的办法是进行签名或哈希校验再加载:

#!/bin/bash

#检查文件签名或哈希
expected_hash="45626d89c487f717fedfd769bce914f1eb7e73fccb341544aa7645af4b41945d"
actual_hash=$(sha256sum config.cfg | cut -d' ' -f1)

if [[ "$expected_hash" != "$actual_hash" ]]; then
    echo "错误:配置文件哈希不匹配"
    exit 1
fi

source config.cfg

echo $DB_HOST
echo $DB_PORT

1.3、sed解析

#!/bin/bash

# sed解析
while IFS='=' read -r key value; do
    # 跳过注释和空行
    [[ "$key" =~ ^#.*$ ]] || [[ -z "$key" ]] && continue
    
    # 去除可能的空格和引号
    key=$(echo $key | tr -d '[:space:]')
    value=$(echo $value | tr -d '[:space:]' | sed "s/^['\"]//;s/['\"]$//")
    
    # 赋值给变量
    declare "$key=$value"
done < config.cfg

# 使用配置
echo "数据库主机: $DB_HOST"
echo "数据库端口: $DB_PORT"

1.4、解析数组

配置文件示例(config.txt):

# 应用配置
APP_NAME="MyApp"
APP_VERSION=1.0.0

# 逗号分隔的数组
ADMIN_USERS="user1,user2,user3"
ALLOWED_IPS="192.168.1.1,192.168.1.2,10.0.0.1"
FEATURES="auth,logging,dashboard,api"

读取脚本:

#!/bin/bash

# 加载配置文件函数
load_csv_config() {
    local config_file="$1"

    # 检查文件是否存在
    [ -f "$config_file" ] || { echo "错误: 配置文件不存在"; exit 1; }
    
    # 逐行处理配置文件
    while IFS='=' read -r key value; do
        # 跳过注释和空行
        [[ "$key" =~ ^#.*$ ]] || [[ -z "$key" ]] && continue
        
        # 去除键和值的首尾空格
        key=$(echo "$key" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
        value=$(echo "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
        
        # 去除值两端的引号
        value=${value%\"}
        value=${value#\"}
        
        # 检查是否是逗号分隔的值
        if [[ "$value" == *,* ]]; then
            # 临时修改IFS来分割数组
            local IFS=','
            # 读取为数组
            read -ra array <<< "$value"
            # 恢复默认IFS
            unset IFS
            
            # 创建数组变量
            declare -ag "${key}=(${array[*]})"
        else
            # 普通变量赋值
            declare -g "$key=$value"
        fi
    done < "$config_file"
}

# 加载配置文件
load_csv_config "config.txt"

# 使用配置
echo "应用名称: $APP_NAME"
echo "应用版本: $APP_VERSION"

echo -e "\n管理员用户:"
printf "  - %s\n" "${ADMIN_USERS[@]}"

echo -e "\n允许的IP地址:"
printf "  - %s\n" "${ALLOWED_IPS[@]}"

echo -e "\n功能特性:"
echo "${FEATURES[@]}"

二、INI格式配置文件

1.1、配置文件示例

app.ini

[database]
host=127.0.0.1
port=3306
user=root
password=secret

[application]
debug=true
log_level=warning

1.2、sed解析

#!/bin/bash

# 使用awk解析INI文件
parse_ini() {
    local ini_file="$1"
    local section=""
    
    while IFS= read -r line; do
        line=$(echo "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
        
        # 跳过注释和空行
        [[ -z "$line" ]] || [[ "$line" =~ ^\; ]] || [[ "$line" =~ ^\# ]] && continue
        
        # 处理节头
        if [[ "$line" =~ ^\[(.*)\]$ ]]; then
            section="${BASH_REMATCH[1]}"
        # 处理键值对
        elif [[ "$line" =~ ^([^=]+)=(.*)$ ]]; then
            key="${BASH_REMATCH[1]}"
            value="${BASH_REMATCH[2]}"

            # 去除首尾空格
            key=$(echo "$key" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
            value=$(echo "$value" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
            

            # 创建变量名 SECTION_KEY
            if [[ -n "$section" ]]; then
                var_name="${section}_${key}"
            else
                var_name="$key"
            fi
            
            # 赋值
            declare -g "$var_name=$value"
        fi
    done < "$ini_file"
}

parse_ini "app.ini"

# 使用配置
echo "数据库主机: ${database_host}"
echo "应用日志级别: ${application_log_level}"
echo $application_debug

1.3、ini配置带数组(显式声明数组)

app1.ini

[application]
name = My Application
version = 1.2.3

[arrays]
admin_users[] = admin1
admin_users[] = admin2
admin_users[] = admin3

allowed_ips[] = 192.168.1.1
allowed_ips[] = 192.168.1.2
allowed_ips[] = 10.0.0.1

config_paths[] = /etc/app/config.d
config_paths[] = /var/lib/app/config
config_paths[] = ~/.app/config
#!/bin/bash

# 声明关联数组存储配置
declare -A config
declare -a admin_users allowed_ips config_paths

# 解析INI文件函数
parse_ini() {
    local ini_file="$1"
    local current_section=""

    [ -f "$ini_file" ] || { echo "错误: 文件不存在"; return 1; }

    while IFS= read -r line; do
        # 移除注释和空格
        line="${line%%[;#]*}"  # 移除注释
        line="${line##[[:space:]]}"  # 移除前导空格
        line="${line%%[[:space:]]}"  # 移除尾部空格

        # 跳过空行
        [ -z "$line" ] && continue

        # 处理节(section)
        if [[ "$line" =~ ^\[(.+)\]$ ]]; then
            current_section="${BASH_REMATCH[1]}"
            continue
        fi

        # 处理数组元素 匹配以某些字符开头[]结尾的即key
        if [[ "$line" =~ ^([^[:space:]=]+)\[\] ]]; then
            local array_name="${BASH_REMATCH[1]}"
            local value="${line#*=[[:space:]]}"
            value="${value%%[[:space:]]}"

            # 去除值两端的引号
            value="${value%\"}"
            value="${value#\"}"
            value="${value%\'}"
            value="${value#\'}"

            # 处理波浪线路径扩展
            if [[ "$value" =~ ^~ ]]; then
                value="${value/#\~/$HOME}"
            fi

            # 根据数组名称添加到对应数组
            case "$array_name" in
                "admin_users") admin_users+=("$value") ;;
                "allowed_ips") allowed_ips+=("$value") ;;
                "config_paths") config_paths+=("$value") ;;
            esac
            continue
        fi

        # 处理普通键值对
        if [[ "$line" =~ ^([^[:space:]=]+)[[:space:]]*=[[:space:]]*(.*)$ ]]; then
            local key="${BASH_REMATCH[1]}"
            local value="${BASH_REMATCH[2]}"

            # 去除值两端的引号
            value="${value%\"}"
            value="${value#\"}"
            value="${value%\'}"
            value="${value#\'}"

            # 存储到关联数组
            if [ -n "$current_section" ]; then
                config["${current_section}.${key}"]="$value"
            else
                config["${key}"]="$value"
            fi
        fi
    done < "$ini_file"
}

# 使用示例
parse_ini "app1.ini"

# 访问配置值
echo "应用名称: ${config[application.name]}"
echo "应用版本: ${config[application.version]}"

# 访问数组配置
echo -e "\n管理员用户:"
printf " - %s\n" "${admin_users[@]}"

echo -e "\n允许的IP地址:"
printf " - %s\n" "${allowed_ips[@]}"

echo -e "\n配置路径:"
printf " - %s\n" "${config_paths[@]}"
echo "${config_paths[@]}"

# 验证路径是否存在
echo -e "\n验证配置路径是否存在:"
for path in "${config_paths[@]}"; do
    if [ -e "$path" ]; then
        echo " [存在] $path"
    else
        echo " [不存在] $path"
    fi
done

1.4、ini配置带数组(逗号分隔数组)

配置文件app2.ini

[application]
name = My Application
version = 1.2.3

[arrays]
admin_users = admin1,admin2,admin3

allowed_ips = 192.168.1.1,192.168.1.2,10.0.0.1

config_paths = /etc/app/config.d,/var/lib/app/config,~/.app/config

解析app2.sh

#!/bin/bash

# 声明关联数组存储配置
declare -A config
declare -a admin_users allowed_ips config_paths

# 解析INI文件函数
parse_ini() {
    local ini_file="$1"
    local current_section=""
    
    [ -f "$ini_file" ] || { echo "错误: 文件不存在"; return 1; }
    
    while IFS= read -r line; do
        # 移除注释和空格
        line="${line%%[;#]*}"  # 移除注释
        line="${line##[[:space:]]}"  # 移除前导空格
        line="${line%%[[:space:]]}"  # 移除尾部空格
        
        # 跳过空行
        [ -z "$line" ] && continue
        
        # 处理节(section)
        if [[ "$line" =~ ^\[(.+)\]$ ]]; then
            current_section="${BASH_REMATCH[1]}"
            continue
        fi
        
        # 处理键值对
        if [[ "$line" =~ ^([^[:space:]=]+)[[:space:]]*=[[:space:]]*(.*)$ ]]; then
            local key="${BASH_REMATCH[1]}"
            local value="${BASH_REMATCH[2]}"
            
            # 去除值两端的引号
            value="${value%\"}"
            value="${value#\"}"
            value="${value%\'}"
            value="${value#\'}"
            
            # 处理波浪线路径扩展
            if [[ "$value" =~ ^~ ]]; then
                value="${value/#\~/$HOME}"
            fi
            
            # 存储到关联数组
            if [ -n "$current_section" ]; then
                config["${current_section}.${key}"]="$value"
            else
                config["${key}"]="$value"
            fi
            
            # 处理逗号分隔的数组
            if [[ "$value" == *,* ]]; then
                case "$key" in
                    "admin_users")
                        IFS=',' read -ra admin_users <<< "$value"
                        ;;
                    "allowed_ips")
                        IFS=',' read -ra allowed_ips <<< "$value"
                        ;;
                    "config_paths")
                        IFS=',' read -ra config_paths <<< "$value"
                        # 处理路径中的波浪线
                        for i in "${!config_paths[@]}"; do
                            if [[ "${config_paths[i]}" =~ ^~ ]]; then
                                config_paths[i]="${config_paths[i]/#\~/$HOME}"
                            fi
                        done
                        ;;
                esac
            fi
        fi
    done < "$ini_file"
}

# 使用示例
parse_ini "app2.ini"

# 访问配置值
echo "应用名称: ${config[application.name]}"
echo "应用版本: ${config[application.version]}"

# 访问数组配置
echo -e "\n管理员用户:"
printf " - %s\n" "${admin_users[@]}"

echo -e "\n允许的IP地址:"
printf " - %s\n" "${allowed_ips[@]}"

echo -e "\n配置路径:"
printf " - %s\n" "${config_paths[@]}"

# 验证路径是否存在
echo -e "\n验证配置路径是否存在:"
for path in "${config_paths[@]}"; do
    if [ -e "$path" ]; then
        echo " [存在] $path"
    else
        echo " [不存在] $path"
    fi
done

# 验证IP地址格式
echo -e "\n验证IP地址格式:"
for ip in "${allowed_ips[@]}"; do
    if [[ "$ip" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        echo " [有效] $ip"
    else
        echo " [无效] $ip"
    fi
done

三、Yaml格式配置文件

3.1、配置文件示例

config.yaml

application:
  name: My Application
  version: 1.2.3

database:
  host: localhost
  port: 3306
  credentials:
    username: admin
    password: secret123

features:
  - logging
  - auth
  - api

3.2、安装yq工具

yq是一个强大的YAML处理工具,类似于jq但专门用于YAML。

# 使用pip安装
pip install yq

# 或者使用包管理器
# Ubuntu/Debian
sudo apt-get install yq

# CentOS/RHEL
sudo yum install yq

# macOS
brew install yq

3.3、使用yq工具解析

#!/bin/bash

# 读取简单值
app_name=$(yq e '.application.name' config.yaml)
app_version=$(yq e '.application.version' config.yaml)

# 读取嵌套值
db_host=$(yq e '.database.host' config.yaml)
db_port=$(yq e '.database.port' config.yaml)

# 读取数组
features=$(yq e '.features[]' config.yaml)

# 输出结果
echo "应用名称: $app_name"
echo "应用版本: $app_version"
echo "数据库主机: $db_host"
echo "数据库端口: $db_port"
echo "功能特性:"
echo "$features" | while read -r feature; do
  echo " - $feature"
done

3.4、使用python的PyYAML库

如果系统中有Python,可以使用PyYAML库解析YAML。

#!/bin/bash

# 使用Python解析YAML
parse_yaml() {
    python3 -c "
import yaml
import sys

with open('$1') as f:
    config = yaml.safe_load(f)
    
    # 输出为Shell变量格式
    def print_items(d, prefix=''):
        for k, v in d.items():
            if isinstance(v, dict):
                print_items(v, f'{prefix}{k}_')
            else:
                print(f'{prefix}{k}=\"{v}\"')
    
    print_items(config)
"
}

# 加载配置
eval "$(parse_yaml config.yaml)"

# 使用配置
echo "应用名称: $application_name"
echo "应用版本: $application_version"
echo "数据库主机: $database_host"
echo "数据库端口: $database_port"
echo "数据库用户名: $database_credentials_username"

四、JSON格式配置文件

4.1、配置文件示例

config.json

{
  "application": {
    "name": "My App",
    "version": "1.2.3",
    "debug": false
  },
  "database": {
    "host": "localhost",
    "port": 3306,
    "credentials": {
      "username": "admin",
      "password": "secret123"
    }
  },
  "features": ["logging", "auth", "api"]
}

4.2、安装jq

jq是一个强大的命令行JSON处理器,非常适合处理JSON配置文件。

# Ubuntu/Debian
sudo apt-get install jq

# CentOS/RHEL
sudo yum install jq

# macOS
brew install jq

4.3、jq读取配置脚本

#!/bin/bash

# 检查jq是否安装
if ! command -v jq &> /dev/null; then
    echo "错误: 需要安装jq工具"
    exit 1
fi

# 检查配置文件是否存在
if [ ! -f "config.json" ]; then
    echo "错误: 配置文件config.json不存在"
    exit 1
fi

# 读取简单值
app_name=$(jq -r '.application.name' config.json)
app_version=$(jq -r '.application.version' config.json)
debug_mode=$(jq -r '.application.debug' config.json)

# 读取嵌套值
db_host=$(jq -r '.database.host' config.json)
db_port=$(jq -r '.database.port' config.json)
db_user=$(jq -r '.database.credentials.username' config.json)

# 读取数组到Bash数组
mapfile -t features < <(jq -r '.features[]' config.json)

# 输出结果
echo "应用配置:"
echo "  名称: $app_name"
echo "  版本: $app_version"
echo "  调试模式: $debug_mode"
echo "数据库配置:"
echo "  主机: $db_host"
echo "  端口: $db_port"
echo "  用户名: $db_user"
echo "功能特性:"
for feature in "${features[@]}"; do
    echo "  - $feature"
done

4.4、Python的json模块解析

如果系统中有Python,可以使用Python的标准库json来解析JSON文件。

#!/bin/bash

# 使用Python解析JSON
parse_json() {
    python3 -c "
import json
import sys

with open('$1') as f:
    config = json.load(f)
    
    # 输出为Shell变量格式
    def print_items(d, prefix=''):
        for k, v in d.items():
            if isinstance(v, dict):
                print_items(v, f'{prefix}{k}_')
            elif isinstance(v, list):
                print(f'{prefix}{k}=(')
                for item in v:
                    print(f'\"{item}\"')
                print(')')
            else:
                print(f'{prefix}{k}=\"{v}\"')
    
    print_items(config)
"
}

# 加载配置
eval "$(parse_json config.json)"

# 使用配置
echo "应用名称: $application_name"
echo "应用版本: $application_version"
echo "调试模式: $application_debug"
echo "数据库主机: $database_host"
echo "数据库端口: $database_port"
echo "数据库用户名: $database_credentials_username"
echo "功能特性:"
for feature in "${features[@]}"; do
    echo "  - $feature"
done

五、环境变量文件(.env格式)

5.1、配置文件示例

config.env

# 应用配置
APP_NAME="My Application"
APP_VERSION=1.2.3
DEBUG=true

# 数据库配置
DB_HOST=localhost
DB_PORT=3306
DB_USER=admin
DB_PASS="secret123"

# 路径配置
LOG_DIR=/var/log/myapp
CONFIG_DIR="/etc/myapp/config"

5.2、source加载

#!/bin/bash

# 检查.env文件是否存在
if [ ! -f ".env" ]; then
    echo "错误: .env文件不存在"
    exit 1
fi

# 方法1:直接source导入(注意安全问题)
set -a  # 自动导出所有变量
source .env
set +a  # 关闭自动导出

# 使用配置
echo "应用名称: $APP_NAME"
echo "应用版本: $APP_VERSION"
echo "调试模式: $DEBUG"
echo "数据库主机: $DB_HOST"
echo "数据库端口: $DB_PORT"
echo "日志目录: $LOG_DIR"
echo "配置目录: $CONFIG_DIR"

# 验证路径是否存在
if [ ! -d "$LOG_DIR" ]; then
    echo "警告: 日志目录不存在 - $LOG_DIR"
fi

5.3、逐行解析(更安全)

#!/bin/bash

# 安全的.env文件解析函数
load_dotenv() {
    local env_file="$1"
    
    # 检查文件是否存在且可读
    if [ ! -f "$env_file" ] || [ ! -r "$env_file" ]; then
        echo "错误: 无法访问.env文件"
        return 1
    fi
    
    # 逐行处理.env文件
    while IFS= read -r line; do
        # 跳过注释和空行
        [[ "$line" =~ ^[[:space:]]*# ]] && continue
        [[ -z "$line" ]] && continue
        
        # 处理变量赋值
        if [[ "$line" =~ ^([[:alnum:]_]+)=(.*)$ ]]; then
            local var_name="${BASH_REMATCH[1]}"
            local var_value="${BASH_REMATCH[2]}"
            
            # 去除值两端的引号
            var_value="${var_value%\"}"
            var_value="${var_value#\"}"
            var_value="${var_value%\'}"
            var_value="${var_value#\'}"
            
            # 设置变量
            declare -g "$var_name"="$var_value"
            export "$var_name"
        fi
    done < "$env_file"
}

# 加载.env文件
load_dotenv ".env"

echo "应用名称: $APP_NAME"
echo "应用版本: $APP_VERSION"
echo "调试模式: $DEBUG"
echo "数据库主机: $DB_HOST"
echo "数据库端口: $DB_PORT"
echo "日志目录: $LOG_DIR"
echo "配置目录: $CONFIG_DIR"

# 验证路径是否存在
if [ ! -d "$LOG_DIR" ]; then
    echo "警告: 日志目录不存在 - $LOG_DIR"
fi

5.4、完整案例(生产级实现)

#!/bin/bash

# 安全的.env文件加载函数
load_dotenv_safe() {
    local env_file="$1"
    local line var_name var_value
    
    # 检查文件是否存在
    if [ ! -f "$env_file" ]; then
        echo "错误: .env文件不存在" >&2
        return 1
    fi
    
    # 检查文件权限
    if [ "$(stat -c %a "$env_file")" -gt 600 ]; then
        echo "警告: .env文件权限过于开放" >&2
    fi
    
    # 逐行处理
    while IFS= read -r line; do
        # 跳过注释和空行
        [[ "$line" =~ ^[[:space:]]*# ]] && continue
        [[ -z "${line// }" ]] && continue
        
        # 验证变量名格式
        if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then
            var_name="${BASH_REMATCH[1]}"
            var_value="${BASH_REMATCH[2]}"
            
            # 去除值两端的引号
            var_value="${var_value%\"}"
            var_value="${var_value#\"}"
            var_value="${var_value%\'}"
            var_value="${var_value#\'}"
            
            # 设置变量
            declare -g "$var_name"="$var_value"
            export "$var_name"
        else
            echo "警告: 忽略无效的变量赋值 - $line" >&2
        fi
    done < "$env_file"
    
    # 验证必需变量
    local required_vars=("APP_NAME" "DB_HOST" "DB_PORT")
    for var in "${required_vars[@]}"; do
        if [ -z "${!var}" ]; then
            echo "错误: 必需变量 $var 未设置" >&2
            return 1
        fi
    done
}

# 加载.env文件
load_dotenv_safe ".env" || exit 1

# 设置默认值
: ${DEBUG:=false}
: ${LOG_DIR:=/var/log/myapp}

# 使用配置
echo "应用配置:"
echo "  名称: $APP_NAME"
echo "  版本: $APP_VERSION"
echo "  调试模式: $DEBUG"
echo "数据库配置:"
echo "  主机: $DB_HOST"
echo "  端口: $DB_PORT"
echo "  用户: $DB_USER"
echo "路径配置:"
echo "  日志目录: $LOG_DIR"
echo "  配置目录: $CONFIG_DIR"

# 验证路径
if [ ! -d "$LOG_DIR" ]; then
    echo "创建日志目录: $LOG_DIR"
    mkdir -p "$LOG_DIR" || {
        echo "错误: 无法创建日志目录" >&2
        exit 1
    }
fi

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2379402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

答题pk小程序道具卡的获取与应用

道具卡是答题PK小程序中必不可少的一项增加趣味性的辅助应用&#xff0c;那么道具卡是如何获取与应用的呢&#xff0c;接下来我们来揭晓答案&#xff1a; 一、道具卡的获取&#xff1a; 签到获取&#xff1a;在每日签到中签到不仅可获得当日的签到奖励积分&#xff0c;同时连…

leetcode3265. 统计近似相等数对 I-medium

1 题目&#xff1a;统计近似相等数对 I 官方标定难度&#xff1a;中 给你一个正整数数组 nums 。 如果我们执行以下操作 至多一次 可以让两个整数 x 和 y 相等&#xff0c;那么我们称这个数对是 近似相等 的&#xff1a; 选择 x 或者 y 之一&#xff0c;将这个数字中的两个…

【架构篇】代码组织结构设计

代码组织结构设计&#xff1a;模块化分层与高效协作实践 摘要 本文以Java项目为例&#xff0c;解析后端代码组织的标准化结构&#xff0c;涵盖模块划分原则、依赖管理策略及实际应用场景。通过模块化设计提升代码可维护性、团队协作效率及系统扩展能力。 一、模块化设计的核心…

日期数据渲染转换问题

今天在学习Springboot框架时&#xff0c;想做一个非常简单的增删改查巩固一下&#xff0c;结果在数据渲染上出现了一个小问题&#xff0c;如图数据库中的数据一切正常 但是在前端渲染时&#xff0c;是下面这个效果 这是因为数据库存储的日期类型数据在前端渲染时&#xff0c;没…

ubuntu18.04编译qt5.14.2源码

ubuntu18.04编译qt5.14.2源码 文章目录 ubuntu18.04编译qt5.14.2源码[toc]1 前言2 参考文档3 下载源码3.1 方法13.2 方法23.3 方法3 4 ubuntu编译qt源码4.1 环境准备4.2 设置交换分区大小4.3 编译源码4.4 添加环境变量4.5 验证编译结果4.6 编译帮助文档&#xff08;qch&#xf…

创建指定版本的vite项目

1、获取vite的版本号 npm view create-vite versions 注:4.4.1版本即对应着node16版本的项目 2、创建制定版本的vite项目 npm init vite<version>

iOS 初识RunLoop

iOS 初识RunLoop 文章目录 iOS 初识RunLoopRunLoop的概念RunLoop的功能RunLoop和线程的关系RunLoop的结构ModeObserverTimer 和 source小结 RunLoop的核心RunLoop的流程RunLoop的应用AutoreleasePool响应触控事件刷新界面常驻线程网络请求NSTimer 和 CADisplayLinkNSTimerGCDTi…

电子电路仿真实验教学平台重磅上线!——深圳航天科技创新研究院倾力打造,助力高校教学数字化转型

在传统电子电路课堂中&#xff0c;实验室的灯光总与高昂的成本、拥挤的设备、反复的耗材损耗相伴&#xff0c;而教师不得不面对这样的现实&#xff1a;有限的硬件资源束缚着教学深度&#xff0c;不可逆的实验风险制约着创新探索&#xff0c;固化的时空场景阻碍着个性化学习。当…

搭建一个WordPress网站需要多少成本

WordPress 最初可能只是一个简单的博客平台。但近年来&#xff0c;它不仅成为了最好的博客平台&#xff0c;还成为了一个全面的内容管理系统。白宫、jQuery、NGINX、《纽约时报》等企业都把 WordPress 作为自己的网上家园。 不过&#xff0c;它们只是其中的佼佼者。根据 Built…

Python数据可视化 - Pyecharts绘图示例

文章目录 一、Pyecharts简介及安装1. Pyecharts简介2. 安装Pyecharts 二、准备数据三、饼图示例1. 初始化选项配置2. 饼图相关设置3. 全局配置项3.1 标题配置项3.2 图例配置项3.3 提示框配置项3.4 工具箱配置项3.5 视觉映射配置项 4. 系列配置项4.1 标签选项配置4.2 图元样式配…

NC016NC017美光固态芯片NC101NC102

NC016NC017美光固态芯片NC101NC102 在存储技术的演进历程中&#xff0c;美光科技的NC016、NC017、NC101与NC102系列固态芯片&#xff0c;凭借其技术创新与市场适应性&#xff0c;成为行业关注的焦点。本文将从技术内核、产品性能、行业动向、应用场景及市场价值五个维度&#…

[Android] 青木扫描全能文档3.0,支持自动扫描功能

声明&#xff1a;根据许多帖友的反馈&#xff0c;我也根据重新实测得出结论&#xff1a;该app是提供一天的体验时间&#xff0c;后续还是采取收费才能使用功能的措施。因为现在市面上免费使用的扫描工具很少了&#xff0c;所以当初我初步测试感觉软件不错就发布了出来&#xff…

通俗解释Transformer在处理序列问题高效的原因(个人理解)

Transformer出现的背景 CNN 的全局关联缺陷卷积神经网络&#xff08;CNN&#xff09;通过多层堆叠扩大感受野&#xff0c;但在自然语言处理中存在本质局限&#xff1a; 局部操作的语义割裂&#xff1a;每个卷积核仅处理固定窗口&#xff08;如 3-5 词&#xff09;&#xff0c;…

区间带边权并查集,XY4060泄露的测试点

目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 码蹄集 二、解题报告 1、思路分析 关于带边权并查集&#xff1a;并查集&…

【数据结构】1-4算法的空间复杂度

数据结构知识点合集 知识点 空间复杂度的定义以及计算 空间复杂度--空间开销&#xff08;内存开销&#xff09;与问题规模 n 之间的关系 无论问题规模怎么变&#xff0c;算法运行所需的内存空间都是固定的常量&#xff0c;算法空间复杂度为S(n) O(1)&#xff0c;S 表示 “Spac…

OpenAI推出Codex — ChatGPT内置的软件工程Agents

OpenAI继续让ChatGPT对开发者更加实用。 几天前,他们增加了连接GitHub仓库的支持,可以"Deep Research"并根据你自己的代码提问。 今天,该公司在ChatGPT中推出了Codex的研究预览版,这是迄今为止最强大的AI编码Agent。 它可以编写代码、修复错误、运行测试,并在…

AI日报 · 2025年5月15日|GPT-4.1 登陆 ChatGPT

AI日报 2025年5月15日&#xff5c;GPT-4.1 登陆 ChatGPT 1、OpenAI 在 ChatGPT 全面开放 GPT-4.1 与 GPT-4.1 mini 北京时间 5 月 14 日晚&#xff0c;OpenAI 在官方 Release Notes 中宣布&#xff1a;专为复杂代码与精细指令场景打造的 GPT-4.1 正式加入 ChatGPT&#xff0…

W5500使用ioLibrary库创建TCP客户端

1、WIZnet全硬件TCP/IP协议栈 WIZnet全硬件TCP/IP协议栈,支持TCP,UDP,IPv4,ICMP,ARP,IGMP以及PPPoE协议。 以太网&#xff1a;支持BSD和WIZCHIP&#xff08;W5500/W5300/W5200/W5100/W5100S&#xff09;的SOCKET APIs驱动程序。 互联网&#xff1a; DHCP客户端 DNS客户端 FTP客…

组态王|如何创建组态王工程?

哈喽,你好啊,我是雷工! 组态王是比较普及的组态软件之一,大部分工控人应该都接触过组态王软件, 最近有个用组态王软件开发上位机,对设备进行集中控制的项目,边开发,顺便记录一些使用方法。 本篇从基础的如何创建组态王工程开始记录,以下为操作笔记。 1 、首先在工程…

mysql数据库-3(备份和恢复)

1. 冷备份和还原的实现 简介:冷备份定义是 读、写操作均不可进行,数据库停止服务 (超级简单) 冷备份 需求 对 10.0.0.13 主机实现冷备操作 关闭 10.0.0.13 主机的服务(ubuntu系统为例) 10.0.0.12为远程主机 systemctl stop mysql.service 备份数据 mkdir /data/…