shell脚本(三):sql批量执行脚本

一 实际执行时候用的脚本

#!/bin/sh
mysql -uroot -p123 visualization < /var/tmp/position_info_v2_DataStructure.sql

ls /var/tmp/data/SQLDumpSplitterResult/ | while read line
do
    mysql -uroot -p123 visualization < /var/tmp/data/SQLDumpSplitterResult/$line
    echo "导入文件 $line 完成~~~~~~"
done

1.1 这个脚本存在很多问题

这段 shell 脚本用于将 SQL 文件导入到 MySQL 数据库 visualization 中。让我们来分析一下它的功能和潜在问题:

脚本功能:

  1. 导入 position_info_v2_DataStructure.sql 文件:

    • mysql -uroot -p123 visualization < /var/tmp/position_info_v2_DataStructure.sql
    • 这条命令使用 mysql 客户端连接到 MySQL 服务器(使用 root 用户和密码 123),并执行 position_info_v2_DataStructure.sql 文件中的 SQL 语句。这通常用于创建数据库表结构。
  2. 循环导入 SQLDumpSplitterResult 目录下的所有文件:

    • ls /var/tmp/data/SQLDumpSplitterResult/ | while read line
    • 这条命令使用 ls 列出 /var/tmp/data/SQLDumpSplitterResult/ 目录下的所有文件和子目录,并通过管道 (|) 将文件名传递给 while 循环。
    • mysql -uroot -p123 visualization < /var/tmp/data/SQLDumpSplitterResult/$line
    • 在循环中,对于每个文件名 $line,这条命令使用 mysql 客户端导入相应的文件。
    • echo "导入文件 $line 完成~~~~~~"
    • 导入成功后,输出一条消息。

潜在问题和改进建议:

  1. 密码安全:

    • 直接在命令行中使用密码 (-p123) 是不安全的。密码可能会被其他用户或进程看到。
    • 改进: 使用更安全的方法来提供密码,例如:
      • 使用 ~/.my.cnf 配置文件:
        [client]
        user=root
        password=123
        
      • 使用环境变量:
        export MYSQL_PWD=123
        mysql -uroot visualization < /var/tmp/position_info_v2_DataStructure.sql
        
  2. 错误处理:

    • 脚本没有检查 mysql 命令的返回值。如果导入失败,脚本仍然会输出 “导入文件…完成”。
    • 改进: 添加错误检查:
      if mysql -uroot -p123 visualization < /var/tmp/data/SQLDumpSplitterResult/$line; then
          echo "导入文件 $line 完成~~~~~~"
      else
          echo "导入文件 $line 失败!"
      fi
      
  3. 文件类型检查:

    • 脚本会尝试导入目录下的所有文件,包括非 SQL 文件(如 ReadMe.txt)。这可能导致 SQL 语法错误。
    • 改进: 添加文件类型检查,只导入 .sql 文件:
      if [[ "$line" == *.sql ]]; then
          if mysql -uroot -p123 visualization < /var/tmp/data/SQLDumpSplitterResult/$line; then
              echo "导入文件 $line 完成~~~~~~"
          else
              echo "导入文件 $line 失败!"
          fi
      else
          echo "跳过文件 $line"
      fi
      
  4. 绝对路径:

    • 使用绝对路径 /var/tmp/data/SQLDumpSplitterResult/ 可能会限制脚本的灵活性。
    • 改进: 可以考虑使用相对路径或接受命令行参数来指定目录。

1.2 速记

速记要点:

  • 开头: #!/bin/sh
  • 导入单个文件: mysql -u -p < 文件
  • 循环导入: ls | while read; do mysql < 文件; echo 完成; done
  • 数据库名: visualization
  • 文件路径: /var/tmp/.../var/tmp/data/SQLDumpSplitterResult/

更易记忆的版本:

  • 开头: sh
  • 导入一个: mysql < 单文件
  • 循环导入: 列出 | 循环读; 执行 mysql < 文件; 输出 完成; 结束循环
  • 库名: visualization
  • 文件位置: /var/tmp/...

二 改进后的脚本

#!/bin/sh

# 导入单个 SQL 文件
if mysql -uroot -p123 visualization < /var/tmp/position_info_v2_DataStructure.sql; then
    echo "导入 position_info_v2_DataStructure.sql 完成~~~~~~"
else
    echo "导入 position_info_v2_DataStructure.sql 失败!"
fi

# 循环导入 SQL 文件
ls /var/tmp/data/SQLDumpSplitterResult/ | while read line
do
    if [[ "$line" == *.sql ]]; then  # 仅导入 .sql 文件
        if mysql -uroot -p123 visualization < /var/tmp/data/SQLDumpSplitterResult/$line; then
            echo "导入文件 $line 完成~~~~~~"
        else
            echo "导入文件 $line 失败!"
        fi
    else
        echo "跳过文件 $line"
    fi
done