例如。
me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR
并使用“\”转义符:
me$ FOO="BAR \* BAR"
me$ echo $FOO
BAR \* BAR
我明明做一些愚蠢的事。
如何获取输出“BAR * BAR”?
例如。
me$ FOO="BAR * BAR"
me$ echo $FOO
BAR file1 file2 file3 file4 BAR
并使用“\”转义符:
me$ FOO="BAR \* BAR"
me$ echo $FOO
BAR \* BAR
我明明做一些愚蠢的事。
如何获取输出“BAR * BAR”?
设置$ FOO时引用是不够的。 你需要引用变量的引用,以及:
me$ FOO="BAR * BAR"
me$ echo "$FOO"
BAR * BAR
简答题
像其他人说的 - 你应该总是引用变量,以防止奇怪的行为。 所以,而不只是回声$ foo的使用echo “$ foo”的 。
长的答案
我认为这个例子值得进一步解释,因为有更多的事情比它可能会在它的脸上似乎。
我能看到你的困惑进来,你跑,你可能认为自己的外壳显然是做你的第一个例子,因为后:
所以从你的第一个例子:
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
我有点添加到这个古老的线程。
通常你会使用
$ 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
FOO='BAR * BAR'
echo "$FOO"
echo "$FOO"
这可能是值得进入使用习惯printf
而不是echo
在命令行上。
在这个例子中它并没有给多少好处,但也可以是更复杂的输出更加有用。
FOO="BAR * BAR"
printf %s "$FOO"