Bash 如何对变量进行大括号展开?

Bash 如何对变量进行大括号展开?,bash,shell,brace-expansion,Bash,Shell,Brace Expansion,考虑以下脚本: #! /bin/bash -e echo {foo,bar} EX={foo,bar} echo ${EX} 此脚本的输出为: foo bar {foo,bar} 我希望echo命令在${EX}上执行大括号扩展。因此,我希望看到 foo bar foo bar 我想创建一个脚本,用户可以在其中提供一个带有花括号的路径,在其中复制每个扩展版本 大概是这样的: #! /bin/bash -e $SOURCES=$1 $TARGET=$2 cp -r ${SOURCES}

考虑以下脚本:

#! /bin/bash -e

echo {foo,bar}
EX={foo,bar}
echo ${EX}
此脚本的输出为:

foo bar
{foo,bar}
我希望
echo
命令在
${EX}
上执行大括号扩展。因此,我希望看到

foo bar
foo bar
我想创建一个脚本,用户可以在其中提供一个带有花括号的路径,在其中复制每个扩展版本

大概是这样的:

#! /bin/bash -e

$SOURCES=$1
$TARGET=$2

cp -r ${SOURCES} ${TARGET}

我怎样才能做到这一点呢?

请参见
manbash

展开顺序为:大括号展开、平铺展开、参数展开、变量和算术展开以及命令替换(以从左到右的方式完成)、分词和路径名展开

正如您所看到的,变量扩展发生在大括号扩展之后

幸运的是,您根本不需要它:让用户指定带括号的路径,让shell展开它们。然后你就可以

mv "$@"
如果需要分隔参数,请使用数组和参数展开:

sources=("${@:1:$#-1}")
target=${@: -1}
mv "${sources[@]}" "$target"
这是一种方式:

ex=({foo,bar,baz})
echo ${ex[@]}
foo bar baz

大括号扩展无法按您尝试使用的方式工作。大括号展开基本上用于生成要在当前命令上下文中应用的列表。有两种主要模式可以直接使用大括号展开(还有更多模式可以将大括号展开作为另一个运算符的一部分使用)。两种直接模式用于展开逗号分隔的大括号对中的项目列表。e、 g

$ touch file_{a,b,c,d}.txt
执行命令后,大括号扩展将在当前目录中创建所有四个文件,文件名格式正确:

$ ls -1 file*.txt
file_a.txt
file_b.txt
file_c.txt
file_d.txt
您还可以以类似的方式使用大括号展开来为循环迭代生成列表(或者在需要生成的系统/数字范围的任何地方)。此处使用大括号展开的语法类似,但在大括号内使用了分隔符(
)。
(而不是“
”,“
分隔符)。语法是
{begin..end..increment}
(其中increment可以是正的也可以是负的),例如


注意:如果没有一些可怕的
eval
技巧,就不允许使用变量来
begin
end
increment

什么是
cp-r foo-bar foo-bar
应该做的?也不能用变量进行大括号扩展,正如在他们面前评估的那样,不要把事情弄得过于复杂。您只需编写一次脚本,然后多次(可能)使用它。因此,没有理由试图保存这些值。将值放入数组与使用大括号不同-expansion@DavidC.Rankin这实际上令人惊讶地起到了作用,您可以在其中放置多个大括号,并按照预期进行扩展。移除子字符串的模式扩展就是一个很好的例子。很好的建议-如果您接受已经扩展的参数,那么您的shell脚本的行为更像其他应用程序,并且用户可以以正常的方式使用其shell(而不必引用将由脚本全局化的参数)。为什么
mv“$@”
大括号展开在脚本中时是否有效?什么样的bash构造使这成为可能。这和问题示例有什么不同?(这不起作用)。@mauron85:因为shell扩展了无引号的大括号表达式,而您的脚本会得到一个参数列表。
$ for i in {20..-20..-4}; do echo $i; done)
20
16
12
8
4
0
-4
-8
-12
-16
-20