You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Homestead环境下SQL备份自动导入Bash脚本问题求助

解决Laravel Homestead备份数据库自动导入脚本的遍历异常问题

你的脚本遍历SQL文件的逻辑存在两个核心问题,导致无法正常循环处理每个文件:

  1. 遍历"*.sql"时添加了双引号,shell不会解析通配符,只会把*.sql当作单个文件名处理,而非匹配所有.sql文件
  2. 数据库名提取逻辑未做行限制,若文件中存在多行匹配内容,会导致变量包含换行符,破坏输出格式

修正后的脚本

#!/bin/bash
dirs=()

# 收集所有备份子目录名称
for dir in .backup/mysql_backup/*/; do
    name=${dir#".backup/mysql_backup/"}
    name=${name%"/"}
    dirs+=("$name") 
done

# 获取编号最大的最新备份目录
newest=${dirs[0]}
for n in "${dirs[@]}" ; do
    ((n > newest)) && newest=$n
done

# 验证备份目录存在性
backup_dir=".backup/mysql_backup/$newest"
if [ ! -d "$backup_dir" ]; then
    echo "错误:备份目录 $backup_dir 不存在"
    exit 1
fi
cd "$backup_dir"

# 遍历所有.sql文件并导入
for file in *.sql; do
    # 跳过无匹配文件的情况
    [ ! -f "$file" ] && continue

    # 提取行首匹配的数据库名,仅取第一行结果
    prefix="-- Host: 127.0.0.1    Database: "
    database=$(sed -n "s/^$prefix//p" "$file" | head -n 1)

    # 跳过无法提取数据库名的文件
    [ -z "$database" ] && { echo "警告:文件 $file 未找到数据库名,跳过"; continue; }

    echo "正在导入数据库: $database"
    mysql -u homestead -psecret --port 33060 --host=127.0.0.1 "$database" < "$file"
done

关键修改说明

  • 修复文件遍历:移除"*.sql"的双引号,让shell正确解析通配符;增加文件存在性检查,避免无匹配文件时报错
  • 优化数据库提取:
    • 匹配模式前添加^,确保只匹配行首的注释行,避免误匹配文件内其他相似字符串
    • 用head -n 1限制只取第一行匹配结果,防止变量包含换行符破坏输出格式
  • 增强错误处理:添加备份目录存在性检查、数据库名非空判断,避免脚本静默失败
  • 解释器调整:将#!/bin/sh改为#!/bin/bash,确保(( ))等bash特性正常运行

额外安全建议

不要在命令行明文传递密码-psecret,可以创建~/.my.cnf配置文件:

[client]
user=homestead
password=secret
host=127.0.0.1
port=33060

后续执行mysql命令会自动读取该配置,无需在脚本中暴露密码。

内容的提问来源于stack exchange,提问作者linx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:42:30