【问题标题】:Execute command multiple times with curly brackets arguments list使用大括号参数列表多次执行命令
【发布时间】:2012-12-07 22:50:29
【问题描述】:

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

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 负责?

【问题讨论】:

    标签: bash shell command-line command-line-arguments brace-expansion


    【解决方案1】:

    这称为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 的组合。

    【讨论】:

    • @Shawin Chin,你是对的。我期待命令的多次执行,而不仅仅是扩展参数列表。您为 Brace Expansion 提供的链接非常有用。
    • 我之前也犯过同样的错误,很高兴能帮到你。
    【解决方案2】:

    问题是出乎你的意料,

    大括号展开
    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
    

    【讨论】:

    • 是否有执行多次调用的 bash 表示法?
    • 否;该“符号”将是一个循环,如for i in a b c; do ...; done
    【解决方案3】:

    嗯,你有两个选择:

    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
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-01
      相关资源
      最近更新 更多