MySQL命令在终端可执行但bash脚本中执行失败求助
解决Docker脚本中MySQL密码验证失败的问题
我之前也碰到过一模一样的情况——脚本里的命令单独跑都正常,放一起就报错ERROR 1045 (28000): Access denied,折腾了好一会儿才找到根源。先看看你的脚本问题出在哪:
#!/bin/bash
echo ""
read -s -p "Enter DB Password : " dbpass
echo ""
echo ""
docker run --name mariadb -p 3306:3306 -e MYSQL_ROOT_PASSWORD=$dbpass -e MYSQL_DATABASE=db -d mariadb:10.2.14
sleep 5
docker exec -i mariadb mysql -u root -p$dbpass < mysql.sql
问题根源有两个:
- 固定sleep时间不可靠:
sleep 5只能保证容器启动,但MariaDB服务可能还在初始化(比如初始化数据库、创建用户),这时候执行mysql命令必然会被拒绝。 - 变量未加引号导致解析异常:如果你的密码包含特殊字符(比如空格、
$、!),$dbpass不加双引号的话,shell会提前解析这些字符,导致传递给MySQL的密码和你输入的不一致。即使密码没有特殊字符,不加引号也可能因为shell的词拆分逻辑出问题。
修正后的脚本写法
#!/bin/bash echo "" read -s -p "Enter DB Password : " dbpass echo "" echo "" # 启动MariaDB容器,给密码变量加双引号 docker run --name mariadb -p 3306:3306 -e MYSQL_ROOT_PASSWORD="$dbpass" -e MYSQL_DATABASE=db -d mariadb:10.2.14 # 循环等待数据库服务真正就绪,代替固定sleep until docker exec mariadb mysqladmin ping -u root -p"$dbpass" --silent; do echo "等待数据库启动中..." sleep 2 done # 导入SQL文件,同样给密码变量加双引号 docker exec -i mariadb mysql -u root -p"$dbpass" db < mysql.sql
为什么手动执行没问题?
手动输入命令时,你会下意识等容器里的数据库完全启动再操作,而且终端输入密码时,特殊字符会被正确处理(比如你输入带$的密码时,终端不会提前解析)。但脚本是按顺序执行的,不会等服务就绪,变量解析也完全依赖shell的规则,所以才会出现“单独跑正常,脚本跑失败”的情况。
内容的提问来源于stack exchange,提问作者d2ce
相关产品推荐
相关产品推荐

