我就是做不到。如果 * 在变量中,则扩展为当前文件夹中的文件列表。echo "*" 工作正常。
#!/bin/bash
c="GRANT ALL ON \*.* TO '$1'@'localhost';"
mysql < $c
exit 0;
Run Code Online (Sandbox Code Playgroud)
始终在变量替换周围放置双引号,否则*shell 会解释空格和出现在值中的字符。即,写"$c",不是$c。
该语法mysql <"$c"使mysql从名称为 的值的文件中执行命令$c。你要找的是
printf '%s\n' "$c" | mysql
Run Code Online (Sandbox Code Playgroud)
或者更简单,只要你记住这些限制($c不能以 a 开头-,如果它包含\在 bash 中就可以了,但在 sh 的其他一些变体中则不行)
echo "$c" | mysql
Run Code Online (Sandbox Code Playgroud)
如果命令是多行的,还有另一种更舒适的选择。它被称为“此处文档”。该字符串EOF并不特殊(尽管它是传统的),任何字母和数字序列都可以。终止EOF可以不用空白之前。你需要把\每一个之前$,\并且`除非你想他们解释的外壳。
mysql <<EOF
GRANT ALL ON *.* TO '$1'@'localhost';
EOF
Run Code Online (Sandbox Code Playgroud)请注意,如果 shell 的参数包含单引号,则您有一个注入向量。以下代码段\在每个\和之前添加了一个'。
set -- "${1//\\/\\\\}"
set -- "${1//\'/\'}"
Run Code Online (Sandbox Code Playgroud)
这是相当丑陋的,这就是为什么如果你要做任何复杂的事情,忘记使用 shell 并使用具有实际 SQL 绑定(perl、python 等)的语言,其中库为你处理所有引用和过程构建.
对字符串使用单引号:
c='GRANT ALL ON *.* TO';
c="${c} '$1'@'localhost';";
Run Code Online (Sandbox Code Playgroud)
可能有更好的方法来做到这一点,但在字符串中包含 $1 使它变得奇怪