mysql密码含特殊字符无语法错误,问题在shell截断或引号使用不当;grant中必须用单引号包裹且不转义,如identified by 'p@ss/wd:123';命令行传参需防shell解析,推荐mysql_config_editor加密存储。

MySQL里密码含@、/、:、$等字符,不是语法错误,是shell提前截断或引号没用对——SQL本身完全支持这些字符。
GRANT语句中密码必须用单引号包裹,且不能转义
MySQL解析器只认单引号内的内容为字面量字符串。只要写成IDENTIFIED BY 'p@ss/wd:123',就完全合法;加反斜杠反而错,比如'p\@ss\/wd\:123'会让MySQL把反斜杠当普通字符存进去,登录时得输带反斜杠的密码。
- 正确:
CREATE USER 'app'@'%' IDENTIFIED BY 'p@ss#word!2024'; - 错误(无引号):
CREATE USER 'app'@'%' IDENTIFIED BY p@ss#word!2024;→ 报ERROR 1064 - 错误(加转义):
IDENTIFIED BY 'p\@ss\#word\!2024';→ 登录失败,密码实际是p@ss#word!2024带反斜杠 - 注意:
IDENTIFIED WITH mysql_native_password BY 'p@ss#word!'在MySQL 8.0+中可绕过caching_sha2_password兼容问题
命令行执行GRANT时,shell会吃掉@和:
你敲mysql -u root -p'pa@ss/wd:123',bash会在传参阶段就把@和:当成URL分隔符切掉,MySQL进程收到的密码可能只剩pa或wd,后续解析直接崩。
- 临时解法:用双引号包住整个参数,内部单引号不冲突:
mysql -u root -p"pa@ss/wd:123" - 但
$在双引号里仍会被shell展开,所以含$时必须用单引号,且确保变量未被提前展开(如脚本中pw='abc$2UY'要写成pw='abc\$2UY'或改用pw="abc\$2UY") - 根本解法:别在命令行传密码,用
mysql_config_editor
优先用mysql_config_editor避免所有shell解析问题
它把密码加密存进~/.mylogin.cnf,所有MySQL客户端工具(包括mysql、mysqldump)自动读取,彻底跳过shell参数解析环节。
- 设置:
mysql_config_editor set --login-path=prod --user=myuser --host=localhost --password,回车后粘贴含任意特殊字符的密码 - 验证:
mysql --login-path=prod -e "SELECT USER();" - 权限必须是
600:chmod 600 ~/.mylogin.cnf,否则MySQL拒绝加载 - 配置文件
my.cnf里也别写password=,老客户端容易把:或/误判为DSN分隔符
最常被忽略的是:错误往往不在MySQL侧,而在你敲命令的那一刻——shell已经把密码切碎了。验证方式很简单:用echo "mysql -u u -p'p@ss'" | hexdump -C看@是否还在原位;不在,就是shell动的手。











