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

如何用Bash运行含ENCRYPT()的MySQL脚本?密码非空报错排查

解决Bash脚本中MySQL ENCRYPT()函数返回NULL的问题

这个错误的核心原因是Bash会解析双引号here-document里的美元符号$,导致你的MySQL语句里的$6$被Bash当成了变量引用——而这个变量根本不存在,所以直接被替换成了空字符串。

具体来说,你的CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))经过Bash处理后,会变成CONCAT('', SUBSTRING(SHA(RAND()), -16)),传给ENCRYPT的盐值完全无效,最终ENCRYPT函数返回NULL,触发了Column 'password' cannot be null的错误。

有两种简单的修复方式:

方式1:用单引号包裹here-document分界符

把<< EOF改成<<'EOF',这样Bash会把here-document里的内容当作纯文本,不会解析任何变量或特殊符号:

#!/bin/bash
db_root_user='root'
db_root_password='rootpassword'
mail_db='mail'
mysql --user="$db_root_user" --password="$db_root_password" <<'EOF'
CREATE DATABASE mail;
USE mail;
CREATE TABLE domains (domain varchar(50) NOT NULL, PRIMARY KEY (domain) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE users (staff_id SMALLINT unsigned NOT NULL,email_addr varchar(100) NOT NULL, password varchar(106) NOT NULL, PRIMARY KEY (email_addr)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO domains (domain) VALUES ('myd1.com'),('myd2.com'),('myd3.com');
INSERT INTO users (staff_id,email_addr, password) VALUES ('1','admin@myd1.com',ENCRYPT('mypassword',CONCAT('$6$', SUBSTRING(SHA(RAND()), -16)))),('1','admin@myd2.com',ENCRYPT('mypassword',CONCAT('$6$', SUBSTRING(SHA(RAND()), -16)))),('1','admin@myd3.com',ENCRYPT('mypassword',CONCAT('$6$', SUBSTRING(SHA(RAND()), -16))));
EOF

注意:这种方式下,原来的$mail_db变量也不会被Bash解析了,所以需要把库名改成硬编码的mail,或者拆分语句单独传递变量。

方式2:转义美元符号

保留双引号的here-document,但把$6$里的$转义成\$,让Bash保留这些符号不做解析:

#!/bin/bash
db_root_user='root'
db_root_password='rootpassword'
mail_db='mail'
mysql --user="$db_root_user" --password="$db_root_password" << EOF
CREATE DATABASE $mail_db;
USE $mail_db;
CREATE TABLE domains (domain varchar(50) NOT NULL, PRIMARY KEY (domain) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE users (staff_id SMALLINT unsigned NOT NULL,email_addr varchar(100) NOT NULL, password varchar(106) NOT NULL, PRIMARY KEY (email_addr)) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO domains (domain) VALUES ('myd1.com'),('myd2.com'),('myd3.com');
INSERT INTO users (staff_id,email_addr, password) VALUES ('1','admin@myd1.com',ENCRYPT('mypassword',CONCAT('\$6\$', SUBSTRING(SHA(RAND()), -16)))),('1','admin@myd2.com',ENCRYPT('mypassword',CONCAT('\$6\$', SUBSTRING(SHA(RAND()), -16)))),('1','admin@myd3.com',ENCRYPT('mypassword',CONCAT('\$6\$', SUBSTRING(SHA(RAND()), -16))));
EOF

这种方式的好处是原来的$mail_db变量依然能被Bash正确解析,不需要修改其他语句,是更推荐的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:18:45