保护反对替换

时间:2013-08-25 21:32:46

标签: bash scripting

我有一个自定义的mysql备份脚本,这个脚本的一部分应该执行这样的声明(意图删除.gz):

mysql -uroot -pmypass -e "CREATE DATABASE IF NOT EXISTS `basename -s .gz test-db.gz`" 

但它不起作用并产生错误:

ERROR 1064 (42000) at line 1: 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 '-db' at line 1

我知道问题在于连字符“ - ”,它将test和db分开。

此声明有效

mysql -uroot -pmypass -e "CREATE DATABASE IF NOT EXISTS \`test-db.gz\`"

那么,如何让上面的语句工作,包括我需要的命令替换?

1 个答案:

答案 0 :(得分:4)

背后的原因是mysql不允许您创建名称包含连字符的数据库。解决方法是将带有反引号的数据库名称括起来,这些反引号在MYSQL中具有特殊含义以转义保留字。

反引号在shell中有另一个含义,用于命令替换,因此在这种情况下我们需要使用$()表示命令或嵌套反引号,我个人更喜欢前者因为它更具可读性另外,由于2013年不推荐使用反引号来支持$()语法。

我设法重现了您面临的问题,以下命令对我来说很好。在这里,我们正在逃避反引号,以便shell不会将它们解释为命令替换,而mysql仍将它们用作逃避" - "在" test-db"

mysql -uroot -p -e "CREATE DATABASE IF NOT EXISTS \`$(basename -s .gz test-db.gz)\`"

mysql -uroot -p -e "CREATE DATABASE IF NOT EXISTS \``basename -s .gz test-db.gz`\`"

但是,如果以后需要删除该数据库或对其执行任何数据库级操作,则需要用反引号括起数据库名称,例如

drop database `test-db`;

以下是mysql中有关在数据库名称中使用连字符的错误的link