news 2026/5/11 18:26:23

shell脚本案例(dns主从服务配置)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
shell脚本案例(dns主从服务配置)

dns主从服务配置

主服务器shell脚本

#!/bin/bash set -euo pipefail #============configuration parameters=========== MASTER_IP="192.168.153.131" DOMAIN="web.com" REV_ZONE="153.168.192.in-addr.arpa" SLAVE_IP="192.168.153.132" #=============tool parameters============= info(){ echo -e "\033[32m[info] $1\033[0m"; } warn() { echo -e "\033[33m[WARN] $1\033[0m"; } error() { echo -e "\033[31m[ERROR] $1\033[0m"; exit 1; } #dynamic cursor spinner(){ local pid=$1 local msg=$2 local spin="\|/-" local i=0 while kill -0 $pid 2>/dev/null; do i=$(( (i+1) %4 )) echo -ne "\r[${spin:$i:1}] $msg" sleep 0.1 done echo -ne "\r[√] $msg\n" } #=============main============= clear info "=============== DNS primary server configuration script ===============" info "主服务器IP: $MASTER_IP" info "域名: $DOMAIN" info "反向区域: $REV_ZONE" info "从服务器IP: $SLAVE_IP" info "===================================================" #check if the user is the root user if [ "$(id -u)" -ne 0 ]; then error "please run the script as the root user(sudo -i 或 su -)" fi # 1. install bind package info "step1/6:Installing bind package..." dnf install -y bind bind-utils &>/dev/null || error "Failed to install bind package. Check your repository." # 2. Configure named.conf info "step2/6:Configuring /etc/named.conf..." cat > /etc/named.conf << EOF options { listen-on port 53 { $MASTER_IP; 127.0.0.1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; allow-query { any; }; allow-transfer { $SLAVE_IP; }; dnssec-validation no; recursion no; }; # forward resolution zone zone "$DOMAIN" IN { type master; file "$DOMAIN.zone"; }; # reverse resolution zone zone "$REV_ZONE" IN { type master; file "$REV_ZONE.zone"; }; EOF # 立即设置 named.conf 的权限 info "Setting permissions for /etc/named.conf..." chown root:named /etc/named.conf || error "Failed to change owner of /etc/named.conf" chmod 640 /etc/named.conf || error "Failed to change permissions of /etc/named.conf" # 3. Configure forward zone file info "step3/6:Configuring forward zone file ($DOMAIN.zone)..." cat > /var/named/$DOMAIN.zone << EOF \$TTL 1D @ IN SOA ns1.$DOMAIN. admin.$DOMAIN. ( $(date +%Y%m%d%H) 1D 1H 1W 3H ) NS ns1.$DOMAIN. NS ns2.$DOMAIN. ns1 A $MASTER_IP ns2 A $SLAVE_IP www A $MASTER_IP EOF # 4. Configure reverse zone file info "step4/6:Configuring reverse zone file ($REV_ZONE.zone)..." MASTER_IP_LAST=$(echo $MASTER_IP | awk -F'.' '{print $4}') cat > /var/named/$REV_ZONE.zone << EOF \$TTL 1D @ IN SOA ns1.$DOMAIN. admin.$DOMAIN. ( $(date +%Y%m%d%H) 1D 1H 1W 3H ) NS ns1.$DOMAIN. NS ns2.$DOMAIN. $MASTER_IP_LAST PTR ns1.$DOMAIN. $MASTER_IP_LAST PTR www.$DOMAIN. EOF # 立即设置区域文件的权限 info "Setting permissions for zone files..." chown root:named /var/named/$DOMAIN.zone /var/named/$REV_ZONE.zone || error "Failed to change owner of zone files" chmod 640 /var/named/$DOMAIN.zone /var/named/$REV_ZONE.zone || error "Failed to change permissions of zone files" # 5. Final permission and SELinux configuration info "step5/6:Finalizing permissions and SELinux..." # 强制确保 /var/named 目录的权限和上下文正确 info "Securing /var/named directory..." chown root:named /var/named || error "Failed to change owner of /var/named" chmod 770 /var/named || error "Failed to change permissions of /var/named" # 配置防火墙 info "Configuring firewall..." (firewall-cmd --add-port=53/tcp --add-port=53/udp --permanent && firewall-cmd --reload) &>/dev/null & spinner $! "Firewall configuration in progress..." # 配置SELinux if [ "$(getenforce)" = "Enforcing" ]; then info "Configuring SELinux..." (setsebool -P named_write_master_zones on && setsebool -P named_read_master_zones on) &>/dev/null & spinner $! "SELinux booleans in progress..." info "Restoring SELinux contexts..." (restorecon -Rv /var/named && restorecon /etc/named.conf) &>/dev/null & spinner $! "SELinux context restoration in progress..." fi # 6. Start and verify the named service info "step6/6:Starting named service..." systemctl enable --now named &>/dev/null || error "Failed to start named service. Check logs with: journalctl -u named" # 验证服务状态 if systemctl is-active --quiet named; then info "The named service started successfully!" else error "The named service failed to start. Please check the log: journalctl -u named" fi # 最终提示 info "===================================================" info "Master DNS server configuration completed successfully!" info "Verification command: dig @$MASTER_IP www.$DOMAIN" info "Slave server configuration: Please run the setup_dns_slave.sh script on the slave server." info "==================================================="

从服务器shell脚本

#!/bin/bash set -euo pipefail # 开启严格模式,出错立即退出 # ==================== 配置参数(根据实际环境修改)==================== SLAVE_IP="192.168.153.132" # 从服务器IP MASTER_IP="192.168.153.131" # 主服务器IP(用于同步区域文件) DOMAIN="web.com" # 要解析的域名(与主服务器一致) REV_ZONE="153.168.192.in-addr.arpa" # 反向解析区域(与主服务器一致) # ================================================================== # ==================== 工具函数 ==================== info() { echo -e "\033[32m[INFO] $1\033[0m" } warn() { echo -e "\033[33m[WARN] $1\033[0m" } error() { echo -e "\033[31m[ERROR] $1\033[0m" exit 1 } spinner() { local pid=$1 local msg=$2 local spin='\|/-' local i=0 while kill -0 $pid 2>/dev/null; do i=$(( (i+1) %4 )) echo -ne "\r[${spin:$i:1}] $msg" sleep 0.1 done echo -ne "\r[√] $msg\n" } # ================================================== # ==================== 主逻辑 ==================== clear info "=============== DNS 从服务器配置脚本 ===============" info "从服务器IP: $SLAVE_IP" info "主服务器IP: $MASTER_IP" info "域名: $DOMAIN" info "反向区域: $REV_ZONE" info "===================================================" # 1. 检查是否为root用户 if [ "$(id -u)" -ne 0 ]; then error "请以root用户执行脚本(sudo -i 或 su -)" fi # 2. 安装BIND软件 info "步骤1/6:安装BIND软件..." dnf install -y bind bind-utils &>/dev/null & spinner $! "正在安装bind包..." # 3. 配置named.conf info "步骤2/6:配置named.conf..." cat > /etc/named.conf << EOF options { listen-on port 53 { $SLAVE_IP; 127.0.0.1; }; directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; allow-query { any; }; dnssec-validation no; recursion no; }; # 正向解析区域(从服务器) zone "$DOMAIN" IN { type slave; masters { $MASTER_IP; }; file "slaves/$DOMAIN.zone"; }; # 反向解析区域(从服务器) zone "$REV_ZONE" IN { type slave; masters { $MASTER_IP; }; file "slaves/$REV_ZONE.zone"; }; EOF # 立即设置 named.conf 的权限 info "步骤3/6:调整文件和目录权限..." chown root:named /etc/named.conf || error "Failed to change owner of /etc/named.conf" chmod 640 /etc/named.conf || error "Failed to change permissions of /etc/named.conf" # 确保 /var/named 和 slaves 目录权限正确 chown root:named /var/named || error "Failed to change owner of /var/named" chmod 770 /var/named || error "Failed to change permissions of /var/named" # 检查named.conf语法 named-checkconf /etc/named.conf || error "named.conf配置语法错误,请检查脚本配置参数" # 4. 配置防火墙和SELinux info "步骤4/6:配置防火墙和SELinux..." # 配置防火墙,开放53端口 (firewall-cmd --add-port=53/tcp --add-port=53/udp --permanent && firewall-cmd --reload) &>/dev/null & spinner $! "正在配置防火墙..." # 处理SELinux(若开启) if [ "$(getenforce)" = "Enforcing" ]; then info "正在配置SELinux..." (setsebool -P named_write_slave_zones on && setsebool -P named_read_slave_zones on) &>/dev/null & spinner $! "正在设置SELinux布尔值..." info "正在恢复SELinux上下文..." (restorecon -Rv /var/named && restorecon /etc/named.conf) &>/dev/null & spinner $! "正在恢复文件SELinux上下文..." fi # 5. 启动named服务 info "步骤5/6:启动named服务..." systemctl enable --now named &>/dev/null || error "named服务启动失败,请检查日志:journalctl -u named" # 验证服务状态 if systemctl is-active --quiet named; then info "named服务启动成功!" else error "named服务启动失败,状态异常" fi # 6. 等待并验证区域文件同步 info "步骤6/6:等待从主服务器同步区域文件..." SYNC_TIMEOUT=20 SYNC_INTERVAL=2 SYNC_COUNT=0 while [ $SYNC_COUNT -lt $((SYNC_TIMEOUT / SYNC_INTERVAL)) ]; do if [ -f "/var/named/slaves/$DOMAIN.zone" ] && [ -f "/var/named/slaves/$REV_ZONE.zone" ]; then info "区域文件同步成功!" break fi SYNC_COUNT=$((SYNC_COUNT + 1)) echo -ne "\r[INFO] 正在等待同步...(${SYNC_COUNT}s/${SYNC_TIMEOUT}s)" sleep $SYNC_INTERVAL done echo -ne "\r" # 清除等待行 # 同步失败处理 if [ $SYNC_COUNT -ge $((SYNC_TIMEOUT / SYNC_INTERVAL)) ]; then warn "区域文件同步超时!请检查:" warn "1. 主从服务器网络连通性(ping $MASTER_IP)" warn "2. 主服务器named服务是否正常运行" warn "3. 主服务器named.conf中allow-transfer是否包含从服务器IP($SLAVE_IP)" warn "4. 查看从服务器日志:journalctl -u named | grep -i 'transfer'" fi # 最终提示 info "===================================================" info "从服务器配置完成!" info "验证命令(查询从服务器):dig @$SLAVE_IP www.$DOMAIN" info "高可用测试:停止主服务器named服务(systemctl stop named),再查询从服务器验证解析" info "==================================================="

DNS 主从服务器自动化配置脚本笔记

一、脚本概述

1. 核心用途

基于CentOS/RHEL 8+系统,自动化部署BIND(DNS)主从架构,实现域名正向 / 反向解析及高可用:

  • 主服务器:配置正向 / 反向解析区域、开放从服务器同步权限、配置防火墙 / SELinux
  • 从服务器:同步主服务器区域文件、提供备用解析服务、主服务器故障时自动接管

2. 适用环境

  • 操作系统:CentOS 8+/RHEL 8+(依赖dnf包管理器、firewalldSELinux
  • 网络要求:主从服务器网络互通(TCP/UDP 53 端口开放)、root 权限执行
  • 软件依赖:bind(DNS 服务)、bind-utils(DNS 测试工具,如dig

3. 架构核心逻辑

主服务器(192.168.153.131) 从服务器(192.168.153.132) ├─ 配置正向区域(web.com.zone) ├─ 配置slave类型区域 ├─ 配置反向区域(153.168.192.zone) ├─ 从主服务器同步区域文件 ├─ 允许从服务器同步(allow-transfer) ├─ 提供查询服务(与主服务器解析结果一致) └─ 监听53端口接收查询/同步请求 └─ 主服务器故障时自动响应客户端查询

二、脚本结构解析

两个脚本均遵循「配置参数→工具函数→主逻辑」的结构,核心模块如下:

1. 通用模块(主从脚本共用)

模块功能说明
配置参数集中定义 IP、域名、反向区域等核心变量(如MASTER_IPDOMAIN),便于修改
工具函数info/warn/error:日志输出(带颜色区分);spinner:动态进度条(提升体验)
权限检查强制要求 root 用户执行(id -u != 0则退出)
服务验证启动named后检查服务状态(systemctl is-active

2. 主服务器脚本核心逻辑(6 步)

步骤关键操作
安装依赖dnf安装bindbind-utils
配置named.conf监听主服务器 IP、允许从服务器同步、关闭 DNSSEC / 递归
正向区域文件创建web.com.zone,定义ns1/ns2解析、www记录
反向区域文件创建153.168.192.in-addr.arpa.zone,定义PTR反向解析记录
权限 / 安全配置修正named.conf、区域文件、/var/named目录权限;配置防火墙 / SELinux
启动验证启用并启动named,输出验证命令(dig @主IP www.web.com

3. 从服务器脚本核心逻辑(6 步)

步骤关键操作
安装依赖与主服务器一致,安装bindbind-utils
配置named.conf监听从服务器 IP、定义slave类型区域、指向主服务器 IP
权限调整修正named.conf/var/named目录权限(确保同步文件可写)
安全配置开放防火墙 53 端口、配置 SELinux 允许从服务器同步
启动服务启用并启动named,自动向主服务器请求区域同步
同步验证等待 20 秒检查同步文件是否存在,超时输出排查建议

三、使用说明

1. 执行前提

  1. 主从服务器均安装CentOS 8+/RHEL 8+,且网络互通(ping测试)
  2. 主从服务器均配置好yum/dnf源(确保能安装bind
  3. 执行用户为root(或通过sudo -i切换)

2. 执行步骤

  1. 主服务器执行:
    # 上传主服务器脚本(如 setup_dns_master.sh) chmod +x setup_dns_master.sh ./setup_dns_master.sh
  2. 从服务器执行:
    # 上传从服务器脚本(如 setup_dns_slave.sh) chmod +x setup_dns_slave.sh ./setup_dns_slave.sh

3. 验证方法

验证场景命令
主服务器正向解析dig @192.168.153.131 www.web.com(返回192.168.153.131
主服务器反向解析dig @192.168.153.131 -x 192.168.153.131(返回ns1.web.com
从服务器同步验证dig @192.168.153.132 www.web.com(返回与主服务器一致结果)
高可用测试主服务器执行systemctl stop named,再查询从服务器(解析正常)

四、核心改进建

1. 兼容性优化(解决跨版本 / 环境问题)

问题

当前脚本仅支持CentOS 8+(依赖dnf),不兼容CentOS 7yum包管理器);未检查firewalld/bind依赖是否已安装。

解决方案
  • 增加 OS 版本检测,自动适配yum/dnf
    # 在脚本开头添加OS检测 detect_package_manager() { if [ -f /etc/redhat-release ]; then if grep -q "CentOS Linux 7" /etc/redhat-release; then PKG_MGR="yum" else PKG_MGR="dnf" fi else error "不支持的操作系统" fi } # 安装依赖时使用 $PKG_MGR $PKG_MGR install -y bind bind-utils &>/dev/null &
  • 检查firewalld是否安装,未安装则自动安装:
    # 防火墙配置前添加检查 if ! command -v firewall-cmd &>/dev/null; then info "firewalld未安装,正在安装..." $PKG_MGR install -y firewalld &>/dev/null & spinner $! "firewalld安装中..." systemctl enable --now firewalld &>/dev/null fi

2. 错误处理增强(降低排查难度)

问题

当前脚本通过&>/dev/null屏蔽了大部分操作的详细输出,报错时仅提示 “失败”,无法定位具体原因(如区域文件语法错误、权限修改失败)。

解决方案
  • 保留关键操作的错误输出,如named-checkzone/named-checkconf
    # 原代码(屏蔽输出) named-checkzone $DOMAIN /var/named/$DOMAIN.zone || error "正向区域文件语法错误" # 改进后(显示详细错误) if ! named-checkzone $DOMAIN /var/named/$DOMAIN.zone; then error "正向区域文件语法错误,详细信息:$(named-checkzone $DOMAIN /var/named/$DOMAIN.zone 2>&1)" fi
  • 检查后台进程退出码,spinner显示失败状态:
    # 改进spinner函数,支持失败标识 spinner(){ local pid=$1 local msg=$2 local spin="\|/-" local i=0 while kill -0 $pid 2>/dev/null; do i=$(( (i+1) %4 )) echo -ne "\r[${spin:$i:1}] $msg" sleep 0.1 done # 检查进程退出码 wait $pid if [ $? -eq 0 ]; then echo -ne "\r[√] $msg\n" else echo -ne "\r[×] $msg(失败)\n" error "$msg 执行失败,请查看日志" fi }

3. 幂等性优化(支持重复执行)

问题

当前脚本用cat >覆盖式创建文件(如named.conf、区域文件),重复执行会覆盖原有配置;Serial号($(date +%Y%m%d%H))可能因同一小时内重复执行导致同步失败。

解决方案
  • 先备份原有文件,再创建新配置:
    # 配置named.conf前备份 if [ -f /etc/named.conf ]; then cp /etc/named.conf /etc/named.conf.bak.$(date +%Y%m%d%H%M%S) &>/dev/null info "已备份原有named.conf到 /etc/named.conf.bak.$(date +%Y%m%d%H%M%S)" fi
  • 自动递增Serial号(避免重复):
    # 主服务器正向区域文件Serial号改进 # 读取现有Serial号,无则用当前时间,有则+1 CURRENT_SERIAL=$(date +%Y%m%d%H) if [ -f /var/named/$DOMAIN.zone ]; then EXIST_SERIAL=$(grep -E '^[[:space:]]+[0-9]{10,}' /var/named/$DOMAIN.zone | awk '{print $1}') if [ -n "$EXIST_SERIAL" ] && [ "$EXIST_SERIAL" -ge "$CURRENT_SERIAL" ]; then CURRENT_SERIAL=$((EXIST_SERIAL + 1)) fi fi # 区域文件中替换为 $CURRENT_SERIAL

4. 安全性增强(适配生产环境)

问题
  • allow-query {any;}开放所有客户端查询,生产环境存在安全风险
  • 防火墙开放 53 端口给所有主机,未限制合法查询网段
  • SELinux 配置过于宽泛(setsebool named_write_master_zones on
解决方案
  • 限制允许查询的网段(如公司内网192.168.153.0/24):
    # named.conf 中修改 allow-query allow-query { 192.168.153.0/24; 127.0.0.1; };
  • 防火墙规则限制网段:
    # 原代码(开放给any) firewall-cmd --add-port=53/tcp --add-port=53/udp --permanent # 改进后(仅允许内网网段) firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.153.0/24" port port="53" protocol="tcp" accept' --permanent firewall-cmd --add-rich-rule='rule family="ipv4" source address="192.168.153.0/24" port port="53" protocol="udp" accept' --permanent
  • 精细化 SELinux 配置(替代宽泛的setsebool):
    # 主服务器区域文件上下文配置 semanage fcontext -a -t named_zone_t "/var/named/($DOMAIN|$REV_ZONE).zone" restorecon -v /var/named/($DOMAIN|$REV_ZONE).zone

5. 可维护性优化(降低二次开发成本)

问题
  • 主从脚本存在大量重复代码(工具函数、权限配置、防火墙逻辑)
  • 配置参数内嵌在脚本中,批量修改时需编辑两个文件
解决方案
  • 抽离公共模块为独立脚本(如common.sh):
    # common.sh(工具函数+公共配置) info(){ echo -e "\033[32m[info] $1\033[0m"; } warn() { echo -e "\033[33m[WARN] $1\033[0m"; } error() { echo -e "\033[31m[ERROR] $1\033[0m"; exit 1; } spinner(){ ... } # 公共进度条函数 # 主从脚本引用 source ./common.sh
  • 配置参数抽离为独立配置文件(如dns_config.sh):
    # dns_config.sh MASTER_IP="192.168.153.131" SLAVE_IP="192.168.153.132" DOMAIN="web.com" REV_ZONE="153.168.192.in-addr.arpa" ALLOW_QUERY="192.168.153.0/24" # 允许查询的网段 # 主从脚本引用 source ./dns_config.sh

6. 易用性优化(提升用户体验)

问题
  • 无参数校验(如 IP 格式错误、域名非法时脚本直接执行失败)
  • 无帮助信息,新用户无法快速了解脚本用法
  • 从服务器同步超时后需手动排查,未提供自动修复机制
解决方案
  • 增加参数校验(IP 格式、域名合法性):
    # IP格式校验函数 validate_ip() { local ip=$1 if ! [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then error "IP格式错误:$ip" fi } # 执行参数校验 validate_ip $MASTER_IP validate_ip $SLAVE_IP
  • 增加帮助选项(-h):
    if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then echo "用法:$0 [选项]" echo " -h, --help:显示帮助信息" echo " -c, --config:指定配置文件路径(默认:./dns_config.sh)" exit 0 fi
  • 从服务器同步超时自动修复:
    # 同步超时后尝试手动触发同步 if [ $SYNC_COUNT -ge $((SYNC_TIMEOUT / SYNC_INTERVAL)) ]; then warn "区域文件同步超时,尝试手动触发同步..." if ! rndc retransfer $DOMAIN &>/dev/null; then warn "手动同步失败,请执行 journalctl -u named | grep -i 'transfer' 排查" else info "手动同步触发成功,等待3秒后验证..." sleep 3 if [ -f "/var/named/slaves/$DOMAIN.zone" ]; then info "区域文件同步成功!" fi fi fi

7. 功能补充(增强生产可用性)

  • 增加日志记录:将所有操作输出到/var/log/dns_setup.log,方便排查
    # 脚本开头添加日志重定向 LOG_FILE="/var/log/dns_setup.log" exec > >(tee -a $LOG_FILE) 2>&1
  • 服务健康监控:配置定时任务(crontab),检查named服务状态,异常时自动重启
    # 新增健康检查函数 check_named_health() { if ! systemctl is-active --quiet named; then warn "named服务异常,正在重启..." systemctl restart named &>/dev/null fi } # 添加到crontab(每5分钟检查一次) (crontab -l 2>/dev/null; echo "*/5 * * * * /bin/bash $0 --check-health") | crontab -
  • 邮件通知:配置完成或失败后,发送邮件给管理员(依赖mailx
    # 配置完成后发送邮件 send_notify() { echo "DNS主服务器配置完成,验证命令:dig @$MASTER_IP www.$DOMAIN" | mailx -s "DNS配置结果" admin@web.com }

五、总结

1. 脚本优势

  • 自动化程度高:一键完成主从 DNS 配置,无需手动修改配置文件
  • 安全性基础保障:配置了最小权限、SELinux / 防火墙规则
  • 用户体验友好:动态进度条、清晰的日志提示、同步失败排查建议

2. 核心改进优先级

  1. 兼容性优化(支持 CentOS 7/8)→ 2. 错误处理增强(降低排查难度)→ 3. 幂等性优化(支持重复执行)→ 4. 安全性增强(适配生产)→ 5. 可维护性 / 易用性优化
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/11 18:24:47

5分钟掌握音乐解锁:Unlock-Music浏览器端音频解密终极指南

5分钟掌握音乐解锁&#xff1a;Unlock-Music浏览器端音频解密终极指南 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库&#xff1a; 1. https://github.com/unlock-music/unlock-music &#xff1b;2. https://git.unlock-music.dev/um/web 项目地址: h…

作者头像 李华
网站建设 2026/5/11 18:23:47

CANN ops-math Tanh 算子

Tanh 【免费下载链接】ops-math 本项目是CANN提供的数学类基础计算算子库&#xff0c;实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-math 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DT√Atlas A3 训练系列产品/Atlas A3 推理系列产品√A…

作者头像 李华
网站建设 2026/5/11 18:23:36

停止自我感动式努力,把破事交给AI

又到学术写作的关键阶段&#xff0c;无论是本科毕业生的毕业论文、研究生的学位论文&#xff0c;还是科研工作者的学术论文&#xff0c;不少人都深陷论文创作的困境之中&#xff0c;难以自拔。面对空白的文档页面&#xff0c;大脑也随之陷入空白&#xff0c;选题时反复纠结&…

作者头像 李华
网站建设 2026/5/11 18:22:54

微信小程序交互实战(1)— 从bindtap到setData的数据驱动视图更新

1. 从点击按钮到页面更新&#xff1a;小程序交互初体验 第一次接触微信小程序开发时&#xff0c;最让我兴奋的就是点击按钮后页面能实时变化的效果。记得当时我照着官方文档写了个最简单的按钮点击计数器&#xff0c;点击按钮数字就自动增加&#xff0c;那种成就感至今难忘。今…

作者头像 李华