在除了基本*?[...]图案时,击壳提供了扩展的模式匹配等!(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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top