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

gre*_*gor 6 linux bash

我就是做不到。如果 * 在变量中,则扩展为当前文件夹中的文件列表。echo "*" 工作正常。

#!/bin/bash
c="GRANT ALL ON \*.* TO '$1'@'localhost';"
mysql < $c
exit 0;
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 9

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

  2. 该语法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)
  3. 请注意,如果 shell 的参数包含单引号,则您有一个注入向量。以下代码段\在每个\和之前添加了一个'

    set -- "${1//\\/\\\\}"
    set -- "${1//\'/\'}"
    
    Run Code Online (Sandbox Code Playgroud)

    这是相当丑陋的,这就是为什么如果你要做任何复杂的事情,忘记使用 shell 并使用具有实际 SQL 绑定(perl、python 等)的语言,其中库为你处理所有引用和过程构建.


Rob*_*her 6

对字符串使用单引号:

c='GRANT ALL ON *.* TO';
c="${c} '$1'@'localhost';";
Run Code Online (Sandbox Code Playgroud)

可能有更好的方法来做到这一点,但在字符串中包含 $1 使它变得奇怪

  • 这根本不是问题——通配符也不会在双引号内扩展,所以(除了删除反斜杠)这与问题相同。真正的问题是如何使用 `c`,而不是它是如何定义的。有关更多相关解决方案,请参阅 Gilles、slillibri 和 Dennis Williamson 的回答。 (3认同)