我就是做不到。如果 * 在变量中,它会扩展为当前文件夹中的文件列表。echo "*" 工作正常。
#!/bin/bash
c="GRANT ALL ON \*.* TO '$1'@'localhost';"
mysql < $c
exit 0;
答案1
对字符串使用单引号:
c='GRANT ALL ON *.* TO';
c="${c} '$1'@'localhost';";
可能有更好的方法来实现这一点,但在字符串中包含 $1 会让它变得很奇怪
答案2
始终将变量替换放在双引号内,否则值中出现的空格和字符
*
会被 shell 解释。即,写为"$c"
,而不是$c
。该语法
mysql <"$c"
使mysql
执行命令的文件的名称为 的值$c
。您要查找的是printf '%s\n' "$c" | mysql
或者更简单,只要你记住限制(
$c
不能以 开头-
,如果它包含,那么\
在 bash 中是可以的,但在 sh 的其他一些变体中则不行)echo "$c" | mysql
如果命令是多行的,还有另一种更方便的替代方案。它被称为“here-document”。字符串
EOF
并不特殊(尽管它是传统的),任何字母和数字序列都可以。终止符EOF
可以是不是\
前面必须有空格。您需要在每个和之前添加一个$
,除非您希望它们由 shell 解释。\
`
mysql <<EOF GRANT ALL ON *.* TO '$1'@'localhost'; EOF
请注意,如果 shell 的参数包含单引号,则表示存在注入向量。以下代码片段
\
在每个\
and之前添加了一个'
。set -- "${1//\\/\\\\}" set -- "${1//\'/\'}"
这相当丑陋,这就是为什么如果你要做任何复杂的事情,忘记使用 shell 并使用具有实际 SQL 绑定的语言(perl,python 等等),其中库为你处理所有的引用和过程构建。
答案3
这可以在 bash 中工作,不需要转义
#!/bin/bash
mysql -u root -e "GRANT ALL ON *.* TO '$1'@'localhost'"
exit 0;
答案4
没有比这更复杂的了:
#!/bin/bash
c="GRANT ALL ON *.* TO $1@localhost;"
mysql -e "$c"
或者,如果您需要单引号:
#!/bin/bash
c="GRANT ALL ON *.* TO '$1'@'localhost';"
mysql -e "$c"