1

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

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 发出这个命令。

@anubhava 来自打包程序http://www.packer.io/提供脚本

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

1 回答 1

6

!(cookbooks)是一个extglob。默认情况下不启用它们;您需要shopt -s extglob在 bash 的前一行中运行(因为解析器逐行运行)以使其有效。

所以:

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

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

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

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

# 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 '{}' +
于 2014-02-05T17:34:57.530 回答