在 Bash 中转义星号 (*) 字符

在 Bash 中转义星号 (*) 字符

我就是做不到。如果 * 在变量中,它会扩展为当前文件夹中的文件列表。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

  1. 始终将变量替换放在双引号内,否则值中出现的空格和字符*会被 shell 解释。即,写为"$c",而不是$c

  2. 该语法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
    
  3. 请注意,如果 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"

相关内容