如何逃避报价表达式扩展路径扩展模式?
-
22-08-2019 - |
题
在除了基本*
,?
和[...]
图案时,击壳提供了扩展的模式匹配等!(pattern-list)
运算符(“匹配所有除了所述给定模式中的一个”)。该extglob
外壳选项需要设置使用它们。一个示例:
~$ mkdir test ; cd test ; touch file1 file2 file3
~/test$ echo *
file1 file2 file3
~/test$ shopt -s extglob # make sure extglob is set
~/test$ echo !(file2)
file1 file3
如果我通过壳表达到执行它在副壳的程序,操作者将导致错误。这里的直接运行一个子shell测试(在这里我从另一个目录执行,以确保膨胀不会过早地发生):
~/test$ cd ..
~$ bash -c "cd test ; echo *"
file1 file2 file3
~$ bash -c "cd test ; echo !(file2)" # expected output: file1 file3
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'
我已经试过各种逃避的,但没有我来了已经工作正常。我还怀疑extglob
在副壳没有被设置,但是这不是这种情况:
~$ bash -c "shopt -s extglob ; cd test ; echo !(file2)"
bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `cd test ; echo !(file2)'
任何溶液理解!
解决方案
$ bash -O extglob -c 'echo !(file2)' file1 file3
其他提示
的bash解析执行它之前每一行,所以“禁用了javascript -s extglob”不会有当bash是验证文件名匹配模式语法生效。该选项不能在同一行启用。这就是为什么“的bash -O extglob -c‘XYZ’”溶液(来自兰迪普罗克特)的工作原理和是必需的。
下面是另一种方式,如果你想避免eval
,你需要能够打开的 extglob 的开和关子shell中。只要把你的模式在一个变量:
bash -c 'shopt -s extglob; cd test; patt="!(file2)"; echo $patt; shopt -u extglob; echo $patt'
给出了这样的输出:
file1 file3
!(file2)
证明,认为 extglob 被设置和取消。如果第一echo
了周围的$patt
报价,它只是吐出像第二echo
模式(这可能应该有引号)。
好了,我没有用的 extglob 的任何真正的遭遇,但我可以得到它通过在echo
包裹eval
工作:
$ bash -c 'shopt -s extglob ; cd test ; eval "echo !(file2)"'
file1 file3
不隶属于 StackOverflow