bash 使用大括号参数列表多次执行命令
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13971808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Execute command multiple times with curly brackets arguments list
提问by Haralan Dobrev
When I needed to run a command multiple times with a different argument I used this approach (without understanding it fully):
当我需要使用不同的参数多次运行命令时,我使用了这种方法(没有完全理解它):
touch {a,b,c}
Which is equivalent of:
这相当于:
touch a
touch b
touch c
I think the same could be accomplished with the following loop:
我认为同样可以通过以下循环来完成:
for file in {a,b,c}; do touch $file; done
However I've stumbled across a case where this does not work:
但是,我偶然发现了一个不起作用的情况:
pear channel-discover {"pear.phpunit.de","pear.symfony-project.com"}
I have a few questions:
我有几个问题:
- What is the name of what is happening in the first example and what exactly is happening?
- Is it better to use this approach for simple things rather than for-in loops?
- Why the pear command is not working like that? Should the command script implement some techniques to handle such arguments or is it the shell responsible for that?
- 第一个示例中发生的事情的名称是什么,究竟发生了什么?
- 将这种方法用于简单的事情而不是 for-in 循环更好吗?
- 为什么 pear 命令不能这样工作?命令脚本是否应该实现一些技术来处理这些参数,还是由 shell 负责?
回答by Shawn Chin
That's called Brace Expansion, which expands to a space-separated list of the given strings.
这称为Brace Expansion,它扩展为给定字符串的空格分隔列表。
So touch {a,b,c}would be equivalent to
所以touch {a,b,c}将相当于
touch a b c
While touch {a,b,c}xwould be equivalent to:
虽然touch {a,b,c}x相当于:
touch ax bx cx
You pearcommand would essentially be run as:
您的pear命令基本上将运行为:
pear channel-discover pear.phpunit.de pear.symfony-project.com
which may not be what you expected. If you want the command to be run once for each string, use a for loop (which answers your 2nd question), or use a combination of brace expansion and xargs.
这可能不是您所期望的。如果您希望命令为每个字符串运行一次,请使用 for 循环(它回答您的第二个问题),或使用大括号扩展和 xargs 的组合。
回答by Jens
The problem is that contrary to your expectation, the brace expansionof
问题是,违背你的期望,在括号扩展的
touch {a,b,c}
is equivalent to
相当于
touch a b c # NOT 3 separate invocations.
(Use echo {a,b,c}to verify). It appears that pear channel-discoverdoes not accept twoargs. You will probably see the same error with
(echo {a,b,c}用于验证)。似乎pear channel-discover不接受两个参数。您可能会看到相同的错误
pear channel-discover pear.phpunit.de pear.symfony-project.com
回答by yo'
Well, you have two options:
那么,你有两个选择:
for i in "pear.phpunit.de" "pear.symfony-project.com"
do
pear channel-discover "$i"
done
Or a one-liner (but calling xargsinstead of using bash internals):
或单行(但调用xargs而不是使用 bash 内部结构):
echo "pear.phpunit.de" "pear.symfony-project.com" | xargs -n1 pear channel-discover
The former is certainly easier to read by the human, the time efficiency will be basically the same.
前者当然更容易被人类阅读,时间效率会基本相同。

