当我尝试使用sh`echo'rm -rf!(cookbooks)'|中的bash时出现语法错误bash`

时间:2014-02-05 17:31:39

标签: linux bash shell sh packer

当我使用/ bin / sh时,我可以通过回显它来发出命令

vagrant@vagrant:~$ sh
$ echo 'ls' | bash
some.sh

但是当我尝试使用这个命令rm -rf !(cookbooks)时,我得到了这个

$ echo 'rm -rf !(cookbooks)' | bash
bash: line 1: syntax error near unexpected token `('
bash: line 1: `rm -rf !(cookbooks)'

我需要从/ bin / sh发出此命令。

来自包装工http://www.packer.io/供稿脚本

的@anubhava
if [ -d "/opt/chef/chef-solo/" ]; then
  cd /opt/chef/chef-solo
  rm -rf !(cookbooks)
fi

1 个答案:

答案 0 :(得分:6)

!(cookbooks)是一个外展。它们默认不启用;你需要在前一行bash中运行shopt -s extglob(因为解析器逐行操作)才能使其有效。

所以:

printf '%s\n' 'shopt -s extglob' 'rm -rf !(cookbooks)' | bash

...或者您可以通过命令行启用extglobs(感谢chepner附录):

echo 'rm -rf !(cookbooks)' | bash -O extglob

顺便说一句, 可以在POSIX sh中执行此操作,而不使用extglobs。例如:

# wrap in a function to have a separate $@ rather than overriding global
delete_all_but_cookbooks() {
  set --
  for f in *; do
    [ "$f" = "cookbooks" ] || set -- "$@" "$f"
  done
  rm -rf "$@"
}
delete_all_but_cookbooks

...或者更简单,只需使用find:

find . -mindepth 1 -maxdepth 1 -name cookbooks -prune -o -exec rm -rf '{}' +