如何在带有 EOF 的 MySQL 8 和 BASH 中修复引号内的 double/single 引号?

How to fix a double/single quote inside the quotes in a MySQL 8 with BASH with EOF?

如何修复此错误:

 # cat <<EOF | mysql -uroot -p${MYSQL_PASSWD}
 > create database zabbix character set utf8 collate utf8_bin; create user zabbix@localhost identified by '${ZABBIX_PASSWD}';
 > grant all privileges on zabbix.* to '\'zabbix'\'@'\'localhost'\' identified by '${ZABBIX_PASSWD}';
 > flush privileges;
 > exit
 > EOF
 mysql: [Warning] Using a password on the command line interface can be insecure.
 ERROR at line 2: Unknown command '\''.

或者用双引号:

 # cat <<EOF | mysql -uroot -p${MYSQL_PASSWD}
 > create database zabbix character set utf8 collate utf8_bin; create user zabbix@localhost identified by '${ZABBIX_PASSWD}';
 > grant all privileges on zabbix.* to "\""zabbix\""@"\"localhost"\"" identified by '${ZABBIX_PASSWD}';
 > flush privileges;
 > exit
 > EOF
 mysql: [Warning] Using a password on the command line interface can be insecure.
 ERROR at line 2: Unknown command '\"'.

没有 double/single 引号:

# cat <<EOF | mysql -uroot -p${MYSQL_PASSWD}
> create database zabbix character set utf8 collate utf8_bin; create user zabbix@localhost identified by '${ZABBIX_PASSWD}';
> grant all privileges on zabbix.* to zabbix@localhost identified by '${ZABBIX_PASSWD}';
> flush privileges;
> exit
> EOF
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1064 (42000) at line 2: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by ''' at line 1

或仅使用 double/single 个引号:

# cat <<EOF | mysql -uroot -p${MYSQL_PASSWD}
> create database zabbix character set utf8 collate utf8_bin; create user zabbix@localhost identified by '${ZABBIX_PASSWD}';
> grant all privileges on zabbix.* to "zabbix"@"localhost" identified by '${ZABBIX_PASSWD}';
> flush privileges;
> exit
> EOF
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1064 (42000) at line 2: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by ''' at line 1

EOF shell 文件中的错误是否相同?

此处不需要反斜杠。您混淆了 heredoc 的命令行,反之亦然。您还混淆了 mysql 和命令行。这些(命令行、heredoc 和 mysql)中的每一个都有关于单引号和双引号的不同规则。

  1. Mysql 需要用单引号括起来的字符串文字(但也可以使用双引号,但这不是标准的)。
  2. bash 显然有关于单引号和双引号的规则,但它们不适用于此处,因为这是一个 heredoc
  3. 你的 heredoc 不在乎。您的 heredoc 中的内容被视为文件。单引号,双引号,等等。很酷的是 bash 仍然会换出变量,所以它就像一个 SUPERFILE,但它只是一个 heredoc。

像下面这样的东西应该可以正常工作:

cat <<EOF | mysql -uroot -p${MYSQL_PASSWD}
create database zabbix character set utf8 collate utf8_bin; create user 'zabbix'@'localhost' identified by '${ZABBIX_PASSWD}';
grant all privileges on zabbix.* to 'zabbix'@'localhost' identified by '${ZABBIX_PASSWD}';
flush privileges;
exit
EOF

您的变量将被 bash 替换,即使它们周围有单引号,因为 heredoc 不关心。然后所有这些都传递给 mysql 并且 mysql 很高兴,因为您的字符串文字被正确引用了。

最后,如果您真的很喜欢那些双引号,您可以在 heredoc 中使用它们来代替,这不会有什么不同。 bash 将忽略它们,mysql 将允许它们通过。

我撒谎了,还有最后一件事。您可以在声明 heredoc 时使用 <<- ,这样您就可以在 heredoc 中的行前面加上空格,如果您在脚本中执行此操作,这样更容易阅读。你也可以随意命名你的 heredoc,只要它以相同的词结尾(这两个都是脚本 clarity/readability)。您在这里也不需要 cat,因为 mysql 可以直接从文件中使用,而 heredoc 几乎在所有重要的方面都是一个文件。

mysql -uroot -p${MYSQL_PASSWD} <<-MYSQLCOMMANDS
    create database zabbix character set utf8 collate utf8_bin; create user 'zabbix'@'localhost' identified by '${ZABBIX_PASSWD}';
    grant all privileges on zabbix.* to 'zabbix'@'localhost' identified by '${ZABBIX_PASSWD}';
    flush privileges;
    exit
MYSQLCOMMANDS