获取列名并写入文件:Bash脚本执行MySQL查询失败求助
排查你的Bash脚本MySQL执行问题
咱们一步步拆解可能的问题,从最常见的坑开始排查:
1. 先确认db.config的格式是否正确
source ../db.config是加载数据库凭证的关键一步,但如果文件里的变量定义有问题,直接会导致后续命令失效:
- 变量名和值之间不能有空格,比如正确写法是
DB_USER=root,不是DB_USER = root - 如果密码包含特殊字符(比如
$、!、空格),必须用单引号包裹,比如DB_PASS='my$ecr3t_p@ss' - 确保文件最后一行有换行符,否则最后一个变量可能无法被正确读取
可以先手动执行source ../db.config && echo $DB_USER $DB_PASS,看看是否能正确输出用户名和密码,这一步能快速验证凭证是否加载成功。
2. MySQL密码传递的格式与风险问题
你用-p$DB_PASS的写法,存在两个隐患:
- 如果密码为空或者包含特殊字符,会导致MySQL解析命令出错
- 密码会暴露在命令行历史和进程列表里,有安全风险
更稳妥的写法是用--password="$DB_PASS",或者借助环境变量传递:
export MYSQL_PWD="$DB_PASS" mysqlcmd="mysql -u $DB_USER -s -B -q"
这种方式能避免密码泄露,也能更好地处理特殊字符。
3. 检查输出目录是否存在
脚本直接写入../tmpsql/columns.txt,但如果tmpsql目录不存在,会直接报错"No such file or directory"。可以在写入前加一行目录检查:
mkdir -p ../tmpsql
-p参数会自动创建不存在的父目录,避免因目录缺失导致的失败。
4. 改用更稳定的SQL执行方式
用echo ... | $mysqlcmd的管道写法,有时候会因为SQL语句里的特殊字符(比如反引号、换行)被Bash解析出错。可以换成Here Document的写法,更稳定:
$mysqlcmd <<EOF USE INFORMATION_SCHEMA; SELECT * FROM COLUMNS; EOF > ../tmpsql/columns.txt
这种写法能完整保留SQL的格式,避免管道带来的解析问题。
5. 权限排查
- 确保当前用户有权限读取
../db.config(建议设置权限为chmod 600 ../db.config,避免其他用户读取凭证) - 确认MySQL用户
$DB_USER有权限访问INFORMATION_SCHEMA.COLUMNS表(默认是有权限的,但如果做了权限限制,可能会报错) - 检查当前用户是否有权限写入
../tmpsql目录
6. 开启调试模式定位问题
如果还是找不到问题,可以在脚本开头加set -x开启Bash调试模式,会输出每一步执行的命令和变量值,方便定位哪里出了问题:
set -x source ../db.config mysqlcmd="mysql -u $DB_USER -p$DB_PASS -s -B -q" echo "USE INFORMATION_SCHEMA; SELECT * FROM COLUMNS" | $mysqlcmd > ../tmpsql/columns.txt set +x
执行脚本后会看到详细的执行过程,比如变量是否正确替换,MySQL命令是否正确生成。
内容的提问来源于stack exchange,提问作者mastrobirraio




