要“自动化”导入生成的.sql
文件的过程,同时避免试图通过stdin
和传递文件时可能隐藏的所有陷阱stdout
,只需告诉MySQL .sql
使用SOURCE
MySQL中的命令执行生成的文件即可。
在短,但优秀的,语法的答案,从Kshitij苏德,提供了最好的起点。简而言之,根据Kshitij Sood的语法修改OP的命令,并用以下命令替换其中的SOURCE
命令:
#!/bin/bash
mysql -u$user -p$password $dbname -Bse "SOURCE ds_fbids.sql
SOURCE ds_fbidx.sql"
如果数据库名称包含在生成的 .sql
文件中,则可以从命令中删除它。
这里的假设是生成的文件作为单独的文件有效.sql
。通过不让文件重定向,管道传输或由外壳程序以任何其他方式处理文件,就不会因为外壳程序而需要在生成的输出中转义任何字符。关于什么需要逃脱的规则.sql
当然,文件中仍然适用。
my.cnf
在其他答案中,已经很好地解决了如何处理命令行或文件等中密码周围的安全性问题,并提出了一些很好的建议。我最喜欢的答案是丹尼(Danny),涵盖了这一点,包括如何处理cron
工作或其他任何问题。
为了解决对简短答案的评论(问题?):不,它不能与HEREDOC语法一起使用,因为给出了该shell命令。HEREDOC可以用于重定向版本语法(无此-Bse
选项),因为I / O重定向是HEREDOC的基础。如果您需要HEREDOC的功能,最好在创建.sql
文件时使用它,即使它是临时文件,也可以将该文件用作“命令”以与MySQL批处理行一起执行。
#!/bin/bash
cat >temp.sql <<SQL_STATEMENTS
...
SELECT \`column_name\` FROM \`table_name\` WHERE \`column_name\`='$shell_variable';
...
SQL_STATEMENTS
mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
rm -f temp.sql
请记住,由于外壳扩展,您可以在HEREDOC中使用外壳和环境变量。不利的一面是,您必须逃避每一个反推。MySQL使用它们作为标识符的定界符,但是首先获取字符串的shell将它们用作可执行命令定界符。错过了一次MySQL命令的转义,整个过程因错误而爆炸。可以通过在HEREDOC上使用带引号的LimitString来解决整个问题:
#!/bin/bash
cat >temp.sql <<'SQL_STATEMENTS'
...
SELECT `column_name` FROM `table_name` WHERE `column_name`='constant_value';
...
SQL_STATEMENTS
mysql -u $user -p$password $db_name -Be "SOURCE temp.sql"
rm -f temp.sql
以这种方式删除shell扩展,就无需转义反引号和其他shell特殊字符。它还消除了在其中使用外壳程序和环境变量的能力。这样做几乎消除了在外壳程序脚本中使用HEREDOC的好处。
另一个选择是将Bash允许的多行带引号的字符串与批处理语法版本一起使用(带有-Bse
)。我不知道其他外壳,所以我不能说它们是否也可以在其中使用。无论如何,您都需要使用此命令来执行一个以上的.sql
文件SOURCE
,因为该文件不会;
像其他MySQL命令那样被a终止,并且每行只允许一个文件。多行字符串可以用单引号或双引号引起来,这对shell扩展具有正常的影响。它也有与使用HEREDOC语法处理反引号等相同的警告。
可能更好的解决方案是使用脚本语言,Perl,Python等来创建.sql
文件(如OP一样),并SOURCE
使用顶部的简单命令语法来创建该文件。脚本语言在字符串操作方面比外壳程序要好得多,并且大多数语言都具有内置的过程来处理与MySQL交互时所需的引用和转义。