12

当我需要使用不同的参数多次运行命令时,我使用了这种方法(没有完全理解它):

touch {a,b,c}

这相当于:

touch a
touch b
touch c

我认为同样可以通过以下循环来完成:

for file in {a,b,c}; do touch $file; done

但是,我偶然发现了一个不起作用的情况:

pear channel-discover {"pear.phpunit.de","pear.symfony-project.com"}

我有几个问题:

  1. 第一个示例中发生的事情的名称是什么?到底发生了什么?
  2. 将这种方法用于简单的事情而不是 for-in 循环会更好吗?
  3. 为什么 pear 命令不能这样工作?命令脚本是否应该实现一些技术来处理这些参数,还是由 shell 负责?
4

3 回答 3

13

这称为Brace Expansion,它扩展为给定字符串的空格分隔列表。

所以touch {a,b,c}相当于

touch a b c

虽然touch {a,b,c}x相当于:

touch ax bx cx

pear的命令本质上将按以下方式运行:

pear channel-discover pear.phpunit.de pear.symfony-project.com

这可能不是您所期望的。如果您希望对每个字符串运行一次命令,请使用 for 循环(它回答您的第二个问题),或使用大括号扩展和 xargs 的组合。

于 2012-12-20T12:19:28.383 回答
6

问题是出乎你的意料,大括号展开

touch {a,b,c}

相当于

touch a b c   # NOT 3 separate invocations.

echo {a,b,c}用于验证)。似乎pear channel-discover不接受两个参数。您可能会看到相同的错误

pear channel-discover pear.phpunit.de pear.symfony-project.com
于 2012-12-20T12:19:44.747 回答
0

好吧,你有两个选择:

for i in "pear.phpunit.de" "pear.symfony-project.com"
do
  pear channel-discover "$i"
done

或单线(但调用xargs而不是使用 bash 内部):

echo "pear.phpunit.de" "pear.symfony-project.com" | xargs -n1 pear channel-discover

前者当然更容易被人阅读,时间效率基本相同。

于 2014-09-09T14:29:11.883 回答