如何逃脱在bash通配符/星号人物?如何逃脱在bash通配符/星号人物?(How do I esca

2019-05-13 13:29发布

例如。

me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR

并使用“\”转义符:

me$ FOO="BAR \* BAR"
me$ echo $FOO
BAR \* BAR

我明明做一些愚蠢的事。

如何获取输出“BAR * BAR”?

Answer 1:

设置$ FOO时引用是不够的。 你需要引用变量的引用,以及:

me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR


Answer 2:

简答题

像其他人说的 - 你应该总是引用变量,以防止奇怪的行为。 所以,而不只是回声$ foo的使用echo “$ foo”的

长的答案

我认为这个例子值得进一步解释,因为有更多的事情比它可能会在它的脸上似乎。

我能看到你的困惑进来,你跑,你可能认为自己的外壳显然是做你的第一个例子,因为后:

  1. 参数扩展
  2. 文件名扩展

所以从你的第一个例子:

me$ FOO="BAR * BAR"
me$ echo $FOO

参数扩展后相当于:

me$ echo BAR * BAR

和文件名扩展后相当于:

me$ echo BAR file1 file2 file3 file4 BAR

如果你只需要输入echo BAR * BAR在命令行中,你会发现它们是等价的。

所以,你可能认为自己“如果我逃避*,我可以防止文件名扩展”

所以从你的第二个例子:

me$ FOO="BAR \* BAR"
me$ echo $FOO

参数后扩张应相当于:

me$ echo BAR \* BAR

和文件名后扩张应相当于:

me$ echo BAR \* BAR

如果你试图输入“回声BAR \ * BAR”直接进入命令行就确实会打印“BAR * BAR”,因为文件名扩展是由逃逸阻止。

那么,为什么使用$ foo的不行?

这是因为还有第三个扩张,发生 - 引用删除。 从bash的说明书引用的删除是:

前述扩展后,将字符“\”,“””和““”的所有未引用的发生的该没有导致由上述扩展的一个被除去。

所以,当你直接键入命令在命令行中会发生什么时,转义字符不是以前的扩张的结果,从而BASH将其发送到echo命令之前移除,但在第二个例子中,“\ *”号以前的参数扩展的结果,所以它不会被删除。 其结果是,接收回声“\ *”,这就是它打印。

注意第一个例子之间的区别 - “*”,不包含在将被引用删除被删除的字符。

我希望这是有道理的。 最终的结论在相同 - 只是使用引号。 我只是想我会解释为什么逃逸,这在逻辑上应该工作如果只是参数和文件名扩展在作怪,没有工作。

对于bash扩展的完整说明,请参阅:

http://www.gnu.org/software/bash/manual/bashref.html#Shell-Expansions



Answer 3:

我有点添加到这个古老的线程。

通常你会使用

$ echo "$FOO"

但是,我有问题,即使有这样的语法。 请看下面的代码。

#!/bin/bash
curl_opts="-s --noproxy * -O"
curl $curl_opts "$1"

*需要传递逐字至curl ,但也会出现同样的问题。 上面的例子将无法正常工作(这将扩大到在当前目录下的文件名),并没有将\* 。 您也可以不报$curl_opts ,因为这将被视为一个单一的(无效)选项curl

curl: option -s --noproxy * -O: is unknown
curl: try 'curl --help' or 'curl --manual' for more information

因此,我建议使用的bash变量$GLOBIGNORE干脆防止文件名扩展,如果应用到全球格局,或使用set -f内置的标志。

#!/bin/bash
GLOBIGNORE="*"
curl_opts="-s --noproxy * -O"
curl $curl_opts "$1"  ## no filename expansion

适用于您的原来的例子:

me$ FOO="BAR * BAR"

me$ echo $FOO
BAR file1 file2 file3 file4 BAR

me$ set -f
me$ echo $FOO
BAR * BAR

me$ set +f
me$ GLOBIGNORE=*
me$ echo $FOO
BAR * BAR


Answer 4:

FOO='BAR * BAR'
echo "$FOO"


Answer 5:

echo "$FOO"


Answer 6:

这可能是值得进入使用习惯printf而不是echo在命令行上。

在这个例子中它并没有给多少好处,但也可以是更复杂的输出更加有用。

FOO="BAR * BAR"
printf %s "$FOO"


文章来源: How do I escape the wildcard/asterisk character in bash?